diff --git a/.gitignore b/.gitignore
index 915a798c7..b25a8f8b0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
venv/
+.clang-format
.DS_Store
.tags
.ipynb_checkpoints
@@ -6,7 +7,7 @@ venv/
.overlay_init
.overlay_consistent
.sconsign.dblite
-.vscode
+.vscode*
model2.png
a.out
@@ -31,6 +32,7 @@ a.out
*.vcd
config.json
clcache
+compile_commands.json
persist
board/obj/
@@ -42,6 +44,7 @@ selfdrive/ui/_ui
selfdrive/test/longitudinal_maneuvers/out
selfdrive/visiond/visiond
selfdrive/loggerd/loggerd
+selfdrive/loggerd/bootlog
selfdrive/sensord/_gpsd
selfdrive/sensord/_sensord
selfdrive/camerad/camerad
@@ -68,3 +71,6 @@ flycheck_*
cppcheck_report.txt
comma.sh
+
+selfdrive/modeld/thneed/compile
+models/*.thneed
diff --git a/Jenkinsfile b/Jenkinsfile
index a9479a111..32bdc4965 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -1,25 +1,39 @@
def phone(String ip, String step_label, String cmd) {
- def ci_env = "CI=1 TEST_DIR=${env.TEST_DIR} GIT_BRANCH=${env.GIT_BRANCH} GIT_COMMIT=${env.GIT_COMMIT}"
-
withCredentials([file(credentialsId: 'id_rsa_public', variable: 'key_file')]) {
- sh label: step_label,
- script: """
- ssh -tt -o StrictHostKeyChecking=no -i ${key_file} -p 8022 root@${ip} '${ci_env} /usr/bin/bash -le' <<'EOF'
-echo \$\$ > /dev/cpuset/app/tasks || true
-echo \$PPID > /dev/cpuset/app/tasks || true
-mkdir -p /dev/shm
-chmod 777 /dev/shm
+ def ssh_cmd = """
+ssh -tt -o StrictHostKeyChecking=no -i ${key_file} -p 8022 'comma@${ip}' /usr/bin/bash <<'EOF'
+
+set -e
+
+export CI=1
+export TEST_DIR=${env.TEST_DIR}
+export GIT_BRANCH=${env.GIT_BRANCH}
+export GIT_COMMIT=${env.GIT_COMMIT}
+
+source ~/.bash_profile
+
+ln -snf ${env.TEST_DIR} /data/pythonpath
+
+if [ -f /EON ]; then
+ echo \$\$ > /dev/cpuset/app/tasks || true
+ echo \$PPID > /dev/cpuset/app/tasks || true
+ mkdir -p /dev/shm
+ chmod 777 /dev/shm
+fi
+
cd ${env.TEST_DIR} || true
${cmd}
exit 0
+
EOF"""
+
+ sh script: ssh_cmd, label: step_label
}
}
def phone_steps(String device_type, steps) {
lock(resource: "", label: device_type, inversePrecedence: true, variable: 'device_ip', quantity: 1) {
timeout(time: 60, unit: 'MINUTES') {
- phone(device_ip, "kill old processes", "pkill -f comma || true")
phone(device_ip, "git checkout", readFile("selfdrive/test/setup_device_ci.sh"),)
steps.each { item ->
phone(device_ip, item[0], item[1])
@@ -40,7 +54,7 @@ pipeline {
stages {
- stage('Release Build') {
+ stage('Build release2') {
agent {
docker {
image 'python:3.7.3'
@@ -104,16 +118,17 @@ pipeline {
stages {
stage('parallel tests') {
parallel {
-
stage('Devel Build') {
environment {
CI_PUSH = "${env.BRANCH_NAME == 'master' ? 'master-ci' : ' '}"
}
steps {
- phone_steps("eon", [
+ phone_steps("eon-build", [
+ ["build", "SCONS_CACHE=1 scons -j4"],
+ ["test athena", "nosetests -s selfdrive/athena/tests/test_athenad_old.py"],
+ ["test manager", "python selfdrive/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 openpilot", "nosetests -s selfdrive/test/test_openpilot.py"],
- ["test cpu usage", "cd selfdrive/test/ && ./test_cpu_usage.py"],
["test car interfaces", "cd selfdrive/car/tests/ && ./test_car_interfaces.py"],
["test spinner build", "cd selfdrive/ui/spinner && make clean && make"],
["test text window build", "cd selfdrive/ui/text && make clean && make"],
@@ -124,7 +139,8 @@ pipeline {
stage('Replay Tests') {
steps {
phone_steps("eon2", [
- ["camerad/modeld replay", "QCOM_REPLAY=1 scons -j4 && cd selfdrive/test/process_replay && ./camera_replay.py"],
+ ["build QCOM_REPLAY", "SCONS_CACHE=1 QCOM_REPLAY=1 scons -j4"],
+ ["camerad/modeld replay", "cd selfdrive/test/process_replay && ./camera_replay.py"],
])
}
}
@@ -135,13 +151,30 @@ pipeline {
["build", "SCONS_CACHE=1 scons -j4"],
["test sounds", "nosetests -s selfdrive/test/test_sounds.py"],
["test boardd loopback", "nosetests -s selfdrive/boardd/tests/test_boardd_loopback.py"],
- ["test loggerd", "CI=1 python selfdrive/loggerd/tests/test_loggerd.py"],
- //["test camerad", "CI=1 python selfdrive/camerad/test/test_camerad.py"], // wait for shelf refactor
+ ["test loggerd", "python selfdrive/loggerd/tests/test_loggerd.py"],
+ ["test encoder", "python selfdrive/loggerd/tests/test_encoder.py"],
+ ["test camerad", "python selfdrive/camerad/test/test_camerad.py"],
+ ["test logcatd", "python selfdrive/logcatd/tests/test_logcatd_android.py"],
//["test updater", "python installer/updater/test_updater.py"],
])
}
}
+ stage('Tici Build') {
+ environment {
+ R3_PUSH = "${env.BRANCH_NAME == 'master' ? '1' : ' '}"
+ }
+ steps {
+ phone_steps("tici", [
+ ["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"],
+ ["test camerad", "python selfdrive/camerad/test/test_camerad.py"],
+ //["build release3-staging", "cd release && PUSH=${env.R3_PUSH} ./build_release3.sh"],
+ ])
+ }
+ }
+
}
}
}
@@ -158,3 +191,4 @@ pipeline {
}
}
}
+
diff --git a/README.md b/README.md
index 4eb640f96..92545d0a5 100644
--- a/README.md
+++ b/README.md
@@ -77,16 +77,17 @@ Supported Cars
| Honda | CR-V Hybrid 2017-2019 | Honda Sensing | Stock | 0mph | 12mph |
| Honda | Fit 2018-19 | Honda Sensing | openpilot | 25mph1 | 12mph |
| Honda | HR-V 2019-20 | Honda Sensing | openpilot | 25mph1 | 12mph |
-| Honda | Insight 2019-20 | All | Stock | 0mph | 3mph |
+| Honda | Insight 2019-21 | All | Stock | 0mph | 3mph |
| Honda | Inspire 2018 | All | Stock | 0mph | 3mph |
| Honda | Odyssey 2018-20 | Honda Sensing | openpilot | 25mph1 | 0mph |
| Honda | Passport 2019 | All | openpilot | 25mph1 | 12mph |
| Honda | Pilot 2016-19 | Honda Sensing | openpilot | 25mph1 | 12mph |
| Honda | Ridgeline 2017-20 | Honda Sensing | openpilot | 25mph1 | 12mph |
-| Hyundai | Palisade 2020 | All | Stock | 0mph | 0mph |
+| 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 | IS 2017-2019 | All | Stock | 22mph | 0mph |
| Lexus | IS Hybrid 2017 | All | Stock | 0mph | 0mph |
@@ -96,15 +97,16 @@ Supported Cars
| 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 | TSS-P | Stock3| 20mph1 | 0mph |
+| Toyota | Avalon 2016-18, 2021 | 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 |
-| Toyota | C-HR 2017-19 | All | Stock | 0mph | 0mph |
+| Toyota | Camry Hybrid 2021 | All | openpilot | 0mph | 0mph |
+| Toyota | C-HR 2017-20 | All | Stock | 0mph | 0mph |
| Toyota | C-HR Hybrid 2017-19 | All | Stock | 0mph | 0mph |
| Toyota | Corolla 2017-19 | All | Stock3| 20mph1 | 0mph |
| Toyota | Corolla 2020-21 | All | openpilot | 0mph | 0mph |
-| Toyota | Corolla Hatchback 2019-20 | All | openpilot | 0mph | 0mph |
+| Toyota | Corolla Hatchback 2019-21 | All | openpilot | 0mph | 0mph |
| Toyota | Corolla Hybrid 2020-21 | All | openpilot | 0mph | 0mph |
| Toyota | Highlander 2017-19 | All | Stock3| 0mph | 0mph |
| Toyota | Highlander 2020-21 | All | openpilot | 0mph | 0mph |
@@ -113,6 +115,7 @@ Supported Cars
| 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 |
+| Toyota | Prius Prime 2021 | All | openpilot | 0mph | 0mph |
| Toyota | Rav4 2016-18 | TSS-P | Stock3| 20mph1 | 0mph |
| Toyota | Rav4 2019-21 | All | openpilot | 0mph | 0mph |
| Toyota | Rav4 Hybrid 2016-18 | TSS-P | Stock3| 0mph | 0mph |
@@ -129,6 +132,7 @@ 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 |
| Buick | Regal 20181 | Adaptive Cruise | openpilot | 0mph | 7mph |
| Cadillac | ATS 20181 | Adaptive Cruise | openpilot | 0mph | 7mph |
| Chevrolet | Malibu 20171 | Adaptive Cruise | openpilot | 0mph | 7mph |
@@ -136,7 +140,7 @@ Community Maintained Cars and Features
| Chrysler | Pacifica 2017-18 | Adaptive Cruise | Stock | 0mph | 9mph |
| Chrysler | Pacifica 2020 | Adaptive Cruise | Stock | 0mph | 39mph |
| Chrysler | Pacifica Hybrid 2017-18 | Adaptive Cruise | Stock | 0mph | 9mph |
-| Chrysler | Pacifica Hybrid 2019-20 | Adaptive Cruise | Stock | 0mph | 39mph |
+| Chrysler | Pacifica Hybrid 2019-21 | Adaptive Cruise | Stock | 0mph | 39mph |
| Genesis | G70 2018 | All | Stock | 0mph | 0mph |
| Genesis | G80 2018 | All | Stock | 0mph | 0mph |
| Genesis | G90 2018 | All | Stock | 0mph | 0mph |
@@ -148,17 +152,18 @@ Community Maintained Cars and Features
| Hyundai | Ioniq Electric 2020 | SCC + LKAS | Stock | 0mph | 0mph |
| Hyundai | Kona 2020 | SCC + LKAS | Stock | 0mph | 0mph |
| Hyundai | Kona EV 2019 | SCC + LKAS | Stock | 0mph | 0mph |
-| Hyundai | Santa Fe 2019 | All | Stock | 0mph | 0mph |
-| Hyundai | Sonata 2019 | SCC + LKAS | Stock | 0mph | 0mph |
+| Hyundai | Santa Fe 2019-20 | All | Stock | 0mph | 0mph |
+| Hyundai | Sonata 2018-2019 | SCC + LKAS | Stock | 0mph | 0mph |
| 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 | SCC + LKAS | Stock | 0mph | 0mph |
+| Kia | Forte 2018-19, 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 | Sorento 2018 | SCC + LKAS | Stock | 0mph | 0mph |
| Kia | Stinger 2018 | 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 | X-Trail 2017 | ProPILOT | Stock | 0mph | 0mph |
@@ -263,7 +268,7 @@ By using openpilot, you agree to [our Privacy Policy](https://my.comma.ai/privac
Safety and Testing
----
-* openpilot observes ISO26262 guidelines, see [SAFETY.md](SAFETY.md) for more detail.
+* openpilot observes ISO26262 guidelines, see [SAFETY.md](SAFETY.md) for more details.
* openpilot has software in the loop [tests](.github/workflows/test.yaml) that run on every commit.
* The safety model code lives in panda and is written in C, see [code rigor](https://github.com/commaai/panda#code-rigor) for more details.
* panda has software in the loop [safety tests](https://github.com/commaai/panda/tree/master/tests/safety).
@@ -331,8 +336,6 @@ Directory Structure
├── test # Unit tests, system tests and a car simulator
└── ui # The UI
-To understand how the services interact, see `cereal/service_list.yaml`.
-
Licensing
------
diff --git a/RELEASES.md b/RELEASES.md
index c427e60dd..035958c8f 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,20 @@
+Version 0.8.2 (2021-02-26)
+========================
+ * Use model points directly in MPC (no more polyfits), making lateral planning more accurate
+ * Use model heading prediction for smoother lateral control
+ * Smarter actuator delay compensation
+ * Improve qcamera resolution for improved video in explorer and connect
+ * Adjust maximum engagement speed to better fit the model's training distribution
+ * New driver monitoring model trained with 3x more diverse data
+ * Improved face detection with masks
+ * More predictable DM alerts when visibility is bad
+ * Rewritten video streaming between openpilot processes
+ * Improved longitudinal tuning on TSS2 Corolla and Rav4 thanks to briskspirit!
+ * Audi A3 2015 and 2017 support thanks to keeleysam!
+ * Nissan Altima 2020 support thanks to avolmensky!
+ * Lexus ES Hybrid 2018 support thanks to TheInventorMan!
+ * Toyota Camry Hybrid 2021 support thanks to alancyau!
+
Version 0.8.1 (2020-12-21)
========================
* Original EON is deprecated, upgrade to comma two
diff --git a/SConstruct b/SConstruct
index ddca0fe59..4330052df 100644
--- a/SConstruct
+++ b/SConstruct
@@ -17,6 +17,28 @@ AddOption('--asan',
action='store_true',
help='turn on ASAN')
+AddOption('--ubsan',
+ action='store_true',
+ help='turn on UBSan')
+
+AddOption('--clazy',
+ action='store_true',
+ help='build with clazy')
+
+AddOption('--compile_db',
+ action='store_true',
+ help='build clang compilation database')
+
+AddOption('--mpc-generate',
+ action='store_true',
+ help='regenerates the mpc sources')
+
+AddOption('--external-sconscript',
+ action='store',
+ metavar='FILE',
+ dest='external_sconscript',
+ help='add an external SConscript to the build')
+
real_arch = arch = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip()
if platform.system() == "Darwin":
arch = "Darwin"
@@ -27,11 +49,12 @@ if arch == "aarch64" and TICI:
USE_WEBCAM = os.getenv("USE_WEBCAM") is not None
QCOM_REPLAY = arch == "aarch64" and os.getenv("QCOM_REPLAY") is not None
+lenv = {
+ "PATH": os.environ['PATH'],
+}
+
if arch == "aarch64" or arch == "larch64":
- lenv = {
- "LD_LIBRARY_PATH": '/data/data/com.termux/files/usr/lib',
- "PATH": os.environ['PATH'],
- }
+ lenv["LD_LIBRARY_PATH"] = '/data/data/com.termux/files/usr/lib'
if arch == "aarch64":
# android
@@ -43,6 +66,7 @@ if arch == "aarch64" or arch == "larch64":
]
libpath = [
+ "/usr/local/lib",
"/usr/lib",
"/system/vendor/lib64",
"/system/comma/usr/lib",
@@ -71,17 +95,10 @@ if arch == "aarch64" or arch == "larch64":
if QCOM_REPLAY:
cflags += ["-DQCOM_REPLAY"]
cxxflags += ["-DQCOM_REPLAY"]
-
else:
cflags = []
cxxflags = []
-
- lenv = {
- "PATH": "#external/bin:" + os.environ['PATH'],
- }
- cpppath = [
- "#external/tensorflow/include",
- ]
+ cpppath = []
if arch == "Darwin":
libpath = [
@@ -89,15 +106,16 @@ else:
"#cereal",
"#selfdrive/common",
"/usr/local/lib",
+ "/usr/local/opt/openssl/lib",
"/System/Library/Frameworks/OpenGL.framework/Libraries",
]
cflags += ["-DGL_SILENCE_DEPRECATION"]
cxxflags += ["-DGL_SILENCE_DEPRECATION"]
+ cpppath += ["/usr/local/opt/openssl/include"]
else:
libpath = [
"#phonelibs/snpe/x86_64-linux-clang",
"#phonelibs/libyuv/x64/lib",
- "#external/tensorflow/lib",
"#cereal",
"#selfdrive/common",
"/usr/lib",
@@ -106,7 +124,6 @@ else:
rpath = [
"phonelibs/snpe/x86_64-linux-clang",
- "external/tensorflow/lib",
"cereal",
"selfdrive/common"
]
@@ -115,11 +132,14 @@ else:
rpath = [os.path.join(os.getcwd(), x) for x in rpath]
if GetOption('asan'):
- ccflags_asan = ["-fsanitize=address", "-fno-omit-frame-pointer"]
- ldflags_asan = ["-fsanitize=address"]
+ ccflags = ["-fsanitize=address", "-fno-omit-frame-pointer"]
+ ldflags = ["-fsanitize=address"]
+elif GetOption('ubsan'):
+ ccflags = ["-fsanitize=undefined"]
+ ldflags = ["-fsanitize=undefined"]
else:
- ccflags_asan = []
- ldflags_asan = []
+ ccflags = []
+ ldflags = []
# change pythonpath to this
lenv["PYTHONPATH"] = Dir("#").path
@@ -138,11 +158,12 @@ env = Environment(
"-Wno-inconsistent-missing-override",
"-Wno-c99-designator",
"-Wno-reorder-init-list",
- ] + cflags + ccflags_asan,
+ ] + cflags + ccflags,
CPPPATH=cpppath + [
"#",
"#selfdrive",
+ "#phonelibs/catch2/include",
"#phonelibs/bzip2",
"#phonelibs/libyuv/include",
"#phonelibs/openmax/include",
@@ -155,6 +176,7 @@ env = Environment(
"#phonelibs/linux/include",
"#phonelibs/snpe/include",
"#phonelibs/nanovg",
+ "#phonelibs/qrcode",
"#selfdrive/boardd",
"#selfdrive/common",
"#selfdrive/camerad",
@@ -163,14 +185,15 @@ env = Environment(
"#selfdrive/modeld",
"#selfdrive/sensord",
"#selfdrive/ui",
- "#cereal/messaging",
"#cereal",
+ "#cereal/messaging",
+ "#cereal/visionipc",
"#opendbc/can",
],
CC='clang',
CXX='clang++',
- LINKFLAGS=ldflags_asan,
+ LINKFLAGS=ldflags,
RPATH=rpath,
@@ -188,7 +211,7 @@ env = Environment(
tools=["default", "cython", "compilation_db"],
)
-if GetOption('test'):
+if GetOption('compile_db'):
env.CompilationDatabase('compile_commands.json')
if os.environ.get('SCONS_CACHE'):
@@ -239,6 +262,64 @@ else:
Export('envCython')
+# Qt build environment
+qt_env = None
+if arch in ["x86_64", "Darwin", "larch64"]:
+ qt_env = env.Clone()
+
+ qt_modules = ["Widgets", "Gui", "Core", "DBus", "Multimedia", "Network", "Concurrent", "WebEngine", "WebEngineWidgets"]
+
+ qt_libs = []
+ if arch == "Darwin":
+ qt_env['QTDIR'] = "/usr/local/opt/qt"
+ QT_BASE = "/usr/local/opt/qt/"
+ qt_dirs = [
+ QT_BASE + "include/",
+ ]
+ qt_dirs += [f"{QT_BASE}include/Qt{m}" for m in qt_modules]
+ qt_env["LINKFLAGS"] += ["-F" + QT_BASE + "lib"]
+ qt_env["FRAMEWORKS"] += [f"Qt{m}" for m in qt_modules] + ["OpenGL"]
+ else:
+ qt_env['QTDIR'] = "/usr"
+ qt_dirs = [
+ f"/usr/include/{real_arch}-linux-gnu/qt5",
+ 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_dirs += [f"/usr/include/{real_arch}-linux-gnu/qt5/Qt{m}" for m in qt_modules]
+
+ qt_libs = [f"Qt5{m}" for m in qt_modules]
+ if arch == "larch64":
+ qt_libs += ["GLESv2", "wayland-client"]
+ elif arch != "Darwin":
+ qt_libs += ["GL"]
+
+ qt_env.Tool('qt')
+ qt_env['CPPPATH'] += qt_dirs + ["#selfdrive/ui/qt/"]
+ qt_flags = [
+ "-D_REENTRANT",
+ "-DQT_NO_DEBUG",
+ "-DQT_WIDGETS_LIB",
+ "-DQT_GUI_LIB",
+ "-DQT_CORE_LIB"
+ ]
+ qt_env['CXXFLAGS'] += qt_flags
+ qt_env['LIBPATH'] += ['#selfdrive/ui']
+ qt_env['LIBS'] = qt_libs
+
+ if GetOption("clazy"):
+ checks = [
+ "level0",
+ "level1",
+ "no-range-loop",
+ "no-non-pod-global-static",
+ ]
+ 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')
@@ -251,26 +332,32 @@ if SHARED:
else:
cereal = [File('#cereal/libcereal.a')]
messaging = [File('#cereal/libmessaging.a')]
+ visionipc = [File('#cereal/libvisionipc.a')]
+
Export('cereal', 'messaging')
SConscript(['selfdrive/common/SConscript'])
-Import('_common', '_visionipc', '_gpucommon', '_gpu_libs')
+Import('_common', '_gpucommon', '_gpu_libs')
if SHARED:
- common, visionipc, gpucommon = abspath(common), abspath(visionipc), abspath(gpucommon)
+ common, gpucommon = abspath(common), abspath(gpucommon)
else:
common = [_common, 'json11']
- visionipc = _visionipc
gpucommon = [_gpucommon] + _gpu_libs
-Export('common', 'visionipc', 'gpucommon')
+Export('common', 'gpucommon', 'visionipc')
+
+# Build openpilot
+
+SConscript(['cereal/SConscript'])
SConscript(['opendbc/can/SConscript'])
+SConscript(['phonelibs/SConscript'])
+
SConscript(['common/SConscript'])
SConscript(['common/kalman/SConscript'])
SConscript(['common/transformations/SConscript'])
-SConscript(['phonelibs/SConscript'])
SConscript(['selfdrive/camerad/SConscript'])
SConscript(['selfdrive/modeld/SConscript'])
@@ -294,6 +381,10 @@ SConscript(['selfdrive/ui/SConscript'])
if arch != "Darwin":
SConscript(['selfdrive/logcatd/SConscript'])
-if arch == "x86_64":
+if real_arch == "x86_64":
+ SConscript(['tools/nui/SConscript'])
SConscript(['tools/lib/index_log/SConscript'])
+external_sconscript = GetOption('external_sconscript')
+if external_sconscript:
+ SConscript([external_sconscript])
diff --git a/apk/ai.comma.plus.offroad.apk b/apk/ai.comma.plus.offroad.apk
index 90570253e..a99da3ca7 100644
Binary files a/apk/ai.comma.plus.offroad.apk and b/apk/ai.comma.plus.offroad.apk differ
diff --git a/cereal/.gitignore b/cereal/.gitignore
index 40b416ea6..14cd02eff 100644
--- a/cereal/.gitignore
+++ b/cereal/.gitignore
@@ -6,10 +6,16 @@ package-lock.json
__pycache__
.*.swp
.*.swo
-libcereal*.a
+*.os
+*.o
+*.a
+
+test_runner
+
libmessaging.*
libmessaging_shared.*
services.h
.sconsign.dblite
libcereal_shared.*
.mypy_cache/
+catch2/
diff --git a/cereal/SConscript b/cereal/SConscript
index 192e26c90..bd2cde9c6 100644
--- a/cereal/SConscript
+++ b/cereal/SConscript
@@ -1,4 +1,4 @@
-Import('env', 'envCython', 'arch', 'zmq')
+Import('env', 'envCython', 'arch', 'zmq', 'QCOM_REPLAY')
import shutil
@@ -6,30 +6,28 @@ cereal_dir = Dir('.')
gen_dir = Dir('gen')
messaging_dir = Dir('messaging')
-# TODO: remove src-prefix and cereal from command string. can we set working directory?
+# Build cereal
+
+schema_files = ['log.capnp', 'car.capnp', 'legacy.capnp']
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'],
+env.Command([f'gen/cpp/{s}.c++' for s in schema_files] + [f'gen/cpp/{s}.h' for s in schema_files],
+ schema_files,
f"capnpc --src-prefix={cereal_dir.path} $SOURCES -o c++:{gen_dir.path}/cpp/")
if shutil.which('capnpc-java'):
env.Command(['gen/java/Car.java', 'gen/java/Log.java'],
- ['car.capnp', 'log.capnp'],
+ schema_files,
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([
- 'gen/cpp/car.capnp.c++',
- 'gen/cpp/log.capnp.c++',
-])
+cereal_objects = env.SharedObject([f'gen/cpp/{s}.c++' for s in schema_files])
env.Library('cereal', cereal_objects)
env.SharedLibrary('cereal_shared', cereal_objects)
-cereal_dir = Dir('.')
-services_h = env.Command(['services.h'],
- ['service_list.yaml', 'services.py'],
- 'python3 ' + cereal_dir.path + '/services.py > $TARGET')
+# Build messaging
+
+services_h = env.Command(['services.h'], ['services.py'], 'python3 ' + cereal_dir.path + '/services.py > $TARGET')
messaging_objects = env.SharedObject([
'messaging/messaging.cc',
@@ -52,10 +50,33 @@ if arch == "aarch64":
env.Program('messaging/bridge', ['messaging/bridge.cc'], LIBS=[messaging_lib, 'zmq'])
Depends('messaging/bridge.cc', services_h)
-# different target?
-#env.Program('messaging/demo', ['messaging/demo.cc'], LIBS=[messaging_lib, 'zmq'])
-
envCython.Program('messaging/messaging_pyx.so', 'messaging/messaging_pyx.pyx', LIBS=envCython["LIBS"]+[messaging_lib, "zmq"])
+
+# Build Vision IPC
+vipc_sources = [
+ 'visionipc/ipc.cc',
+ 'visionipc/visionipc_server.cc',
+ 'visionipc/visionipc_client.cc',
+ 'visionipc/visionbuf.cc',
+]
+
+if arch in ["aarch64", "larch64"] and (not QCOM_REPLAY):
+ vipc_sources += ['visionipc/visionbuf_ion.cc']
+else:
+ vipc_sources += ['visionipc/visionbuf_cl.cc']
+
+vipc_objects = env.SharedObject(vipc_sources)
+vipc = env.Library('visionipc', vipc_objects)
+
+
+libs = envCython["LIBS"]+["OpenCL", "zmq", vipc, messaging_lib]
+if arch == "Darwin":
+ del libs[libs.index('OpenCL')]
+ envCython['FRAMEWORKS'] += ['OpenCL']
+envCython.Program('visionipc/visionipc_pyx.so', 'visionipc/visionipc_pyx.pyx', LIBS=libs)
+
+
if GetOption('test'):
env.Program('messaging/test_runner', ['messaging/test_runner.cc', 'messaging/msgq_tests.cc'], LIBS=[messaging_lib])
+ env.Program('visionipc/test_runner', ['visionipc/test_runner.cc', 'visionipc/visionipc_tests.cc'], LIBS=[vipc, messaging_lib, 'zmq', 'pthread', 'OpenCL'])
diff --git a/cereal/car.capnp b/cereal/car.capnp
index a9f2e9034..9a8743f82 100644
--- a/cereal/car.capnp
+++ b/cereal/car.capnp
@@ -11,6 +11,8 @@ $Java.outerClassname("Car");
struct CarEvent @0x9b1657f34caf3ad3 {
name @0 :EventName;
+
+ # event types
enable @1 :Bool;
noEntry @2 :Bool;
warning @3 :Bool; # alerts presented only when enabled or soft disabling
@@ -21,7 +23,6 @@ struct CarEvent @0x9b1657f34caf3ad3 {
permanent @8 :Bool; # alerts presented regardless of openpilot state
enum EventName @0xbaa8c5d505f727de {
- # TODO: copy from error list
canError @0;
steerUnavailable @1;
brakeUnavailable @2;
@@ -36,7 +37,6 @@ struct CarEvent @0x9b1657f34caf3ad3 {
buttonEnable @12;
pedalPressed @13;
cruiseDisabled @14;
- radarCanError @15;
speedTooLow @17;
outOfSpace @18;
overheat @19;
@@ -73,13 +73,11 @@ struct CarEvent @0x9b1657f34caf3ad3 {
preLaneChangeLeft @57;
preLaneChangeRight @58;
laneChange @59;
- internetConnectivityNeeded @61;
communityFeatureDisallowed @62;
lowMemory @63;
stockAeb @64;
ldw @65;
carUnrecognized @66;
- radarCommIssue @67;
driverMonitorLowAcc @68;
invalidLkasSetting @69;
speedTooHigh @70;
@@ -100,9 +98,12 @@ struct CarEvent @0x9b1657f34caf3ad3 {
deviceFalling @90;
fanMalfunction @91;
cameraMalfunction @92;
-
+ gpsMalfunction @94;
startupOneplus @82;
+ processNotRunning @95;
+ radarCanErrorDEPRECATED @15;
+ radarCommIssueDEPRECATED @67;
gasUnavailableDEPRECATED @3;
dataNeededDEPRECATED @16;
modelCommIssueDEPRECATED @27;
@@ -113,6 +114,7 @@ struct CarEvent @0x9b1657f34caf3ad3 {
calibrationProgressDEPRECATED @47;
invalidGiraffeHondaDEPRECATED @49;
invalidGiraffeToyotaDEPRECATED @60;
+ internetConnectivityNeededDEPRECATED @61;
whitePandaUnsupportedDEPRECATED @81;
commIssueWarningDEPRECATED @83;
focusRecoverActiveDEPRECATED @86;
@@ -125,7 +127,6 @@ struct CarEvent @0x9b1657f34caf3ad3 {
# all speeds in m/s
struct CarState {
- errorsDEPRECATED @0 :List(CarEvent.EventName);
events @13 :List(CarEvent);
# car speed
@@ -146,8 +147,8 @@ struct CarState {
brakeLights @19 :Bool;
# steering wheel
- steeringAngle @7 :Float32; # deg
- steeringRate @15 :Float32; # deg/s
+ steeringAngleDeg @7 :Float32;
+ steeringRateDeg @15 :Float32;
steeringTorque @8 :Float32; # TODO: standardize units
steeringTorqueEps @27 :Float32; # TODO: standardize units
steeringPressed @9 :Bool; # if the user is using the steering wheel
@@ -235,6 +236,8 @@ struct CarState {
gapAdjustCruise @11;
}
}
+
+ errorsDEPRECATED @0 :List(CarEvent.EventName);
}
# ******* radar state @ 20hz *******
@@ -278,10 +281,6 @@ struct CarControl {
enabled @0 :Bool;
active @7 :Bool;
- gasDEPRECATED @1 :Float32;
- brakeDEPRECATED @2 :Float32;
- steeringTorqueDEPRECATED @3 :Float32;
-
actuators @6 :Actuators;
cruiseControl @4 :CruiseControl;
@@ -293,7 +292,7 @@ struct CarControl {
brake @1: Float32;
# range from -1.0 - 1.0
steer @2: Float32;
- steerAngle @3: Float32;
+ steeringAngleDeg @3: Float32;
}
struct CruiseControl {
@@ -329,8 +328,6 @@ struct CarControl {
}
enum AudibleAlert {
- # these are the choices from the Honda
- # map as good as you can for your car
none @0;
chimeEngage @1;
chimeDisengage @2;
@@ -342,6 +339,10 @@ struct CarControl {
chimeWarning2Repeat @8;
}
}
+
+ gasDEPRECATED @1 :Float32;
+ brakeDEPRECATED @2 :Float32;
+ steeringTorqueDEPRECATED @3 :Float32;
}
# ****** car param ******
@@ -358,6 +359,7 @@ struct CarParams {
minEnableSpeed @7 :Float32;
minSteerSpeed @8 :Float32;
+ maxSteeringAngleDeg @54 :Float32;
safetyModel @9 :SafetyModel;
safetyModelPassive @42 :SafetyModel = silent;
safetyParam @10 :Int16;
@@ -406,7 +408,6 @@ struct CarParams {
steerActuatorDelay @36 :Float32; # Steering wheel actuator delay in seconds
openpilotLongitudinalControl @37 :Bool; # is openpilot doing the longitudinal control?
carVin @38 :Text; # VIN number queried during fingerprinting
- isPandaBlack @39: Bool;
dashcamOnly @41: Bool;
transmissionType @43 :TransmissionType;
carFw @44 :List(CarFw);
@@ -438,10 +439,19 @@ struct CarParams {
}
struct LateralINDITuning {
- outerLoopGain @0 :Float32;
- innerLoopGain @1 :Float32;
- timeConstant @2 :Float32;
- actuatorEffectiveness @3 :Float32;
+ outerLoopGainBP @4 :List(Float32);
+ outerLoopGainV @5 :List(Float32);
+ innerLoopGainBP @6 :List(Float32);
+ innerLoopGainV @7 :List(Float32);
+ timeConstantBP @8 :List(Float32);
+ timeConstantV @9 :List(Float32);
+ actuatorEffectivenessBP @10 :List(Float32);
+ actuatorEffectivenessV @11 :List(Float32);
+
+ outerLoopGainDEPRECATED @0 :Float32;
+ innerLoopGainDEPRECATED @1 :Float32;
+ timeConstantDEPRECATED @2 :Float32;
+ actuatorEffectivenessDEPRECATED @3 :Float32;
}
struct LateralLQRTuning {
@@ -539,4 +549,6 @@ struct CarParams {
fwdCamera @0; # Standard/default integration at LKAS camera
gateway @1; # Integration at vehicle's CAN gateway
}
+
+ isPandaBlackDEPRECATED @39: Bool;
}
diff --git a/cereal/legacy.capnp b/cereal/legacy.capnp
new file mode 100644
index 000000000..6474f4411
--- /dev/null
+++ b/cereal/legacy.capnp
@@ -0,0 +1,850 @@
+using Cxx = import "./include/c++.capnp";
+$Cxx.namespace("cereal");
+
+using Java = import "./include/java.capnp";
+$Java.package("ai.comma.openpilot.cereal");
+$Java.outerClassname("Legacy");
+
+@0x80ef1ec4889c2a63;
+
+# legacy.capnp: a home for deprecated structs
+
+struct LogRotate @0x9811e1f38f62f2d1 {
+ segmentNum @0 :Int32;
+ path @1 :Text;
+}
+
+struct LiveUI @0xc08240f996aefced {
+ rearViewCam @0 :Bool;
+ alertText1 @1 :Text;
+ alertText2 @2 :Text;
+ awarenessStatus @3 :Float32;
+}
+
+struct OrbslamCorrection @0x8afd33dc9b35e1aa {
+ correctionMonoTime @0 :UInt64;
+ prePositionECEF @1 :List(Float64);
+ postPositionECEF @2 :List(Float64);
+ prePoseQuatECEF @3 :List(Float32);
+ postPoseQuatECEF @4 :List(Float32);
+ numInliers @5 :UInt32;
+}
+
+struct EthernetPacket @0xa99a9d5b33cf5859 {
+ pkt @0 :Data;
+ ts @1 :Float32;
+}
+
+struct CellInfo @0xcff7566681c277ce {
+ timestamp @0 :UInt64;
+ repr @1 :Text; # android toString() for now
+}
+
+struct WifiScan @0xd4df5a192382ba0b {
+ bssid @0 :Text;
+ ssid @1 :Text;
+ capabilities @2 :Text;
+ frequency @3 :Int32;
+ level @4 :Int32;
+ timestamp @5 :Int64;
+
+ centerFreq0 @6 :Int32;
+ centerFreq1 @7 :Int32;
+ channelWidth @8 :ChannelWidth;
+ operatorFriendlyName @9 :Text;
+ venueName @10 :Text;
+ is80211mcResponder @11 :Bool;
+ passpoint @12 :Bool;
+
+ distanceCm @13 :Int32;
+ distanceSdCm @14 :Int32;
+
+ enum ChannelWidth @0xcb6a279f015f6b51 {
+ w20Mhz @0;
+ w40Mhz @1;
+ w80Mhz @2;
+ w160Mhz @3;
+ w80Plus80Mhz @4;
+ }
+}
+
+struct LiveEventData @0x94b7baa90c5c321e {
+ name @0 :Text;
+ value @1 :Int32;
+}
+
+struct ModelData @0xb8aad62cffef28a9 {
+ frameId @0 :UInt32;
+ frameAge @12 :UInt32;
+ frameDropPerc @13 :Float32;
+ timestampEof @9 :UInt64;
+ modelExecutionTime @14 :Float32;
+ gpuExecutionTime @16 :Float32;
+ rawPred @15 :Data;
+
+ path @1 :PathData;
+ leftLane @2 :PathData;
+ rightLane @3 :PathData;
+ lead @4 :LeadData;
+ freePath @6 :List(Float32);
+
+ settings @5 :ModelSettings;
+ leadFuture @7 :LeadData;
+ speed @8 :List(Float32);
+ meta @10 :MetaData;
+ longitudinal @11 :LongitudinalData;
+
+ struct PathData @0x8817eeea389e9f08 {
+ points @0 :List(Float32);
+ prob @1 :Float32;
+ std @2 :Float32;
+ stds @3 :List(Float32);
+ poly @4 :List(Float32);
+ validLen @5 :Float32;
+ }
+
+ struct LeadData @0xd1c9bef96d26fa91 {
+ dist @0 :Float32;
+ prob @1 :Float32;
+ std @2 :Float32;
+ relVel @3 :Float32;
+ relVelStd @4 :Float32;
+ relY @5 :Float32;
+ relYStd @6 :Float32;
+ relA @7 :Float32;
+ relAStd @8 :Float32;
+ }
+
+ struct ModelSettings @0xa26e3710efd3e914 {
+ bigBoxX @0 :UInt16;
+ bigBoxY @1 :UInt16;
+ bigBoxWidth @2 :UInt16;
+ bigBoxHeight @3 :UInt16;
+ boxProjection @4 :List(Float32);
+ yuvCorrection @5 :List(Float32);
+ inputTransform @6 :List(Float32);
+ }
+
+ struct MetaData @0x9744f25fb60f2bf8 {
+ engagedProb @0 :Float32;
+ desirePrediction @1 :List(Float32);
+ brakeDisengageProb @2 :Float32;
+ gasDisengageProb @3 :Float32;
+ steerOverrideProb @4 :Float32;
+ desireState @5 :List(Float32);
+ }
+
+ struct LongitudinalData @0xf98f999c6a071122 {
+ distances @2 :List(Float32);
+ speeds @0 :List(Float32);
+ accelerations @1 :List(Float32);
+ }
+}
+
+struct ECEFPoint @0xc25bbbd524983447 {
+ x @0 :Float64;
+ y @1 :Float64;
+ z @2 :Float64;
+}
+
+struct ECEFPointDEPRECATED @0xe10e21168db0c7f7 {
+ x @0 :Float32;
+ y @1 :Float32;
+ z @2 :Float32;
+}
+
+struct GPSPlannerPoints @0xab54c59699f8f9f3 {
+ curPosDEPRECATED @0 :ECEFPointDEPRECATED;
+ pointsDEPRECATED @1 :List(ECEFPointDEPRECATED);
+ curPos @6 :ECEFPoint;
+ points @7 :List(ECEFPoint);
+ valid @2 :Bool;
+ trackName @3 :Text;
+ speedLimit @4 :Float32;
+ accelTarget @5 :Float32;
+}
+
+struct GPSPlannerPlan @0xf5ad1d90cdc1dd6b {
+ valid @0 :Bool;
+ poly @1 :List(Float32);
+ trackName @2 :Text;
+ speed @3 :Float32;
+ acceleration @4 :Float32;
+ pointsDEPRECATED @5 :List(ECEFPointDEPRECATED);
+ points @6 :List(ECEFPoint);
+ xLookahead @7 :Float32;
+}
+
+struct UiNavigationEvent @0x90c8426c3eaddd3b {
+ type @0: Type;
+ status @1: Status;
+ distanceTo @2: Float32;
+ endRoadPointDEPRECATED @3: ECEFPointDEPRECATED;
+ endRoadPoint @4: ECEFPoint;
+
+ enum Type @0xe8db07dcf8fcea05 {
+ none @0;
+ laneChangeLeft @1;
+ laneChangeRight @2;
+ mergeLeft @3;
+ mergeRight @4;
+ turnLeft @5;
+ turnRight @6;
+ }
+
+ enum Status @0xb9aa88c75ef99a1f {
+ none @0;
+ passive @1;
+ approaching @2;
+ active @3;
+ }
+}
+
+struct LiveLocationData @0xb99b2bc7a57e8128 {
+ status @0 :UInt8;
+
+ # 3D fix
+ lat @1 :Float64;
+ lon @2 :Float64;
+ alt @3 :Float32; # m
+
+ # speed
+ speed @4 :Float32; # m/s
+
+ # NED velocity components
+ vNED @5 :List(Float32);
+
+ # roll, pitch, heading (x,y,z)
+ roll @6 :Float32; # WRT to center of earth?
+ pitch @7 :Float32; # WRT to center of earth?
+ heading @8 :Float32; # WRT to north?
+
+ # what are these?
+ wanderAngle @9 :Float32;
+ trackAngle @10 :Float32;
+
+ # car frame -- https://upload.wikimedia.org/wikipedia/commons/f/f5/RPY_angles_of_cars.png
+
+ # gyro, in car frame, deg/s
+ gyro @11 :List(Float32);
+
+ # accel, in car frame, m/s^2
+ accel @12 :List(Float32);
+
+ accuracy @13 :Accuracy;
+
+ source @14 :SensorSource;
+ # if we are fixing a location in the past
+ fixMonoTime @15 :UInt64;
+
+ gpsWeek @16 :Int32;
+ timeOfWeek @17 :Float64;
+
+ positionECEF @18 :List(Float64);
+ poseQuatECEF @19 :List(Float32);
+ pitchCalibration @20 :Float32;
+ yawCalibration @21 :Float32;
+ imuFrame @22 :List(Float32);
+
+ struct Accuracy @0x943dc4625473b03f {
+ pNEDError @0 :List(Float32);
+ vNEDError @1 :List(Float32);
+ rollError @2 :Float32;
+ pitchError @3 :Float32;
+ headingError @4 :Float32;
+ ellipsoidSemiMajorError @5 :Float32;
+ ellipsoidSemiMinorError @6 :Float32;
+ ellipsoidOrientationError @7 :Float32;
+ }
+
+ enum SensorSource @0xc871d3cc252af657 {
+ applanix @0;
+ kalman @1;
+ orbslam @2;
+ timing @3;
+ dummy @4;
+ }
+}
+
+struct OrbOdometry @0xd7700859ed1f5b76 {
+ # timing first
+ startMonoTime @0 :UInt64;
+ endMonoTime @1 :UInt64;
+
+ # fundamental matrix and error
+ f @2: List(Float64);
+ err @3: Float64;
+
+ # number of inlier points
+ inliers @4: Int32;
+
+ # for debug only
+ # indexed by endMonoTime features
+ # value is startMonoTime feature match
+ # -1 if no match
+ matches @5: List(Int16);
+}
+
+struct OrbFeatures @0xcd60164a8a0159ef {
+ timestampEof @0 :UInt64;
+ # transposed arrays of normalized image coordinates
+ # len(xs) == len(ys) == len(descriptors) * 32
+ xs @1 :List(Float32);
+ ys @2 :List(Float32);
+ descriptors @3 :Data;
+ octaves @4 :List(Int8);
+
+ # match index to last OrbFeatures
+ # -1 if no match
+ timestampLastEof @5 :UInt64;
+ matches @6: List(Int16);
+}
+
+struct OrbFeaturesSummary @0xd500d30c5803fa4f {
+ timestampEof @0 :UInt64;
+ timestampLastEof @1 :UInt64;
+
+ featureCount @2 :UInt16;
+ matchCount @3 :UInt16;
+ computeNs @4 :UInt64;
+}
+
+struct OrbKeyFrame @0xc8233c0345e27e24 {
+ # this is a globally unique id for the KeyFrame
+ id @0: UInt64;
+
+ # this is the location of the KeyFrame
+ pos @1: ECEFPoint;
+
+ # these are the features in the world
+ # len(dpos) == len(descriptors) * 32
+ dpos @2 :List(ECEFPoint);
+ descriptors @3 :Data;
+}
+
+struct KalmanOdometry @0x92e21bb7ea38793a {
+ trans @0 :List(Float32); # m/s in device frame
+ rot @1 :List(Float32); # rad/s in device frame
+ transStd @2 :List(Float32); # std m/s in device frame
+ rotStd @3 :List(Float32); # std rad/s in device frame
+}
+
+struct OrbObservation @0x9b326d4e436afec7 {
+ observationMonoTime @0 :UInt64;
+ normalizedCoordinates @1 :List(Float32);
+ locationECEF @2 :List(Float64);
+ matchDistance @3: UInt32;
+}
+
+struct CalibrationFeatures @0x8fdfadb254ea867a {
+ frameId @0 :UInt32;
+
+ p0 @1 :List(Float32);
+ p1 @2 :List(Float32);
+ status @3 :List(Int8);
+}
+
+struct NavStatus @0xbd8822120928120c {
+ isNavigating @0 :Bool;
+ currentAddress @1 :Address;
+
+ struct Address @0xce7cd672cacc7814 {
+ title @0 :Text;
+ lat @1 :Float64;
+ lng @2 :Float64;
+ house @3 :Text;
+ address @4 :Text;
+ street @5 :Text;
+ city @6 :Text;
+ state @7 :Text;
+ country @8 :Text;
+ }
+}
+
+struct NavUpdate @0xdb98be6565516acb {
+ isNavigating @0 :Bool;
+ curSegment @1 :Int32;
+ segments @2 :List(Segment);
+
+ struct LatLng @0x9eaef9187cadbb9b {
+ lat @0 :Float64;
+ lng @1 :Float64;
+ }
+
+ struct Segment @0xa5b39b4fc4d7da3f {
+ from @0 :LatLng;
+ to @1 :LatLng;
+ updateTime @2 :Int32;
+ distance @3 :Int32;
+ crossTime @4 :Int32;
+ exitNo @5 :Int32;
+ instruction @6 :Instruction;
+
+ parts @7 :List(LatLng);
+
+ enum Instruction @0xc5417a637451246f {
+ turnLeft @0;
+ turnRight @1;
+ keepLeft @2;
+ keepRight @3;
+ straight @4;
+ roundaboutExitNumber @5;
+ roundaboutExit @6;
+ roundaboutTurnLeft @7;
+ unkn8 @8;
+ roundaboutStraight @9;
+ unkn10 @10;
+ roundaboutTurnRight @11;
+ unkn12 @12;
+ roundaboutUturn @13;
+ unkn14 @14;
+ arrive @15;
+ exitLeft @16;
+ exitRight @17;
+ unkn18 @18;
+ uturn @19;
+ # ...
+ }
+ }
+}
+
+struct TrafficEvent @0xacfa74a094e62626 {
+ type @0 :Type;
+ distance @1 :Float32;
+ action @2 :Action;
+ resuming @3 :Bool;
+
+ enum Type @0xd85d75253435bf4b {
+ stopSign @0;
+ lightRed @1;
+ lightYellow @2;
+ lightGreen @3;
+ stopLight @4;
+ }
+
+ enum Action @0xa6f6ce72165ccb49 {
+ none @0;
+ yield @1;
+ stop @2;
+ resumeReady @3;
+ }
+
+}
+
+
+struct AndroidGnss @0xdfdf30d03fc485bd {
+ union {
+ measurements @0 :Measurements;
+ navigationMessage @1 :NavigationMessage;
+ }
+
+ struct Measurements @0xa20710d4f428d6cd {
+ clock @0 :Clock;
+ measurements @1 :List(Measurement);
+
+ struct Clock @0xa0e27b453a38f450 {
+ timeNanos @0 :Int64;
+ hardwareClockDiscontinuityCount @1 :Int32;
+
+ hasTimeUncertaintyNanos @2 :Bool;
+ timeUncertaintyNanos @3 :Float64;
+
+ hasLeapSecond @4 :Bool;
+ leapSecond @5 :Int32;
+
+ hasFullBiasNanos @6 :Bool;
+ fullBiasNanos @7 :Int64;
+
+ hasBiasNanos @8 :Bool;
+ biasNanos @9 :Float64;
+
+ hasBiasUncertaintyNanos @10 :Bool;
+ biasUncertaintyNanos @11 :Float64;
+
+ hasDriftNanosPerSecond @12 :Bool;
+ driftNanosPerSecond @13 :Float64;
+
+ hasDriftUncertaintyNanosPerSecond @14 :Bool;
+ driftUncertaintyNanosPerSecond @15 :Float64;
+ }
+
+ struct Measurement @0xd949bf717d77614d {
+ svId @0 :Int32;
+ constellation @1 :Constellation;
+
+ timeOffsetNanos @2 :Float64;
+ state @3 :Int32;
+ receivedSvTimeNanos @4 :Int64;
+ receivedSvTimeUncertaintyNanos @5 :Int64;
+ cn0DbHz @6 :Float64;
+ pseudorangeRateMetersPerSecond @7 :Float64;
+ pseudorangeRateUncertaintyMetersPerSecond @8 :Float64;
+ accumulatedDeltaRangeState @9 :Int32;
+ accumulatedDeltaRangeMeters @10 :Float64;
+ accumulatedDeltaRangeUncertaintyMeters @11 :Float64;
+
+ hasCarrierFrequencyHz @12 :Bool;
+ carrierFrequencyHz @13 :Float32;
+ hasCarrierCycles @14 :Bool;
+ carrierCycles @15 :Int64;
+ hasCarrierPhase @16 :Bool;
+ carrierPhase @17 :Float64;
+ hasCarrierPhaseUncertainty @18 :Bool;
+ carrierPhaseUncertainty @19 :Float64;
+ hasSnrInDb @20 :Bool;
+ snrInDb @21 :Float64;
+
+ multipathIndicator @22 :MultipathIndicator;
+
+ enum Constellation @0x9ef1f3ff0deb5ffb {
+ unknown @0;
+ gps @1;
+ sbas @2;
+ glonass @3;
+ qzss @4;
+ beidou @5;
+ galileo @6;
+ }
+
+ enum State @0xcbb9490adce12d72 {
+ unknown @0;
+ codeLock @1;
+ bitSync @2;
+ subframeSync @3;
+ towDecoded @4;
+ msecAmbiguous @5;
+ symbolSync @6;
+ gloStringSync @7;
+ gloTodDecoded @8;
+ bdsD2BitSync @9;
+ bdsD2SubframeSync @10;
+ galE1bcCodeLock @11;
+ galE1c2ndCodeLock @12;
+ galE1bPageSync @13;
+ sbasSync @14;
+ }
+
+ enum MultipathIndicator @0xc04e7b6231d4caa8 {
+ unknown @0;
+ detected @1;
+ notDetected @2;
+ }
+ }
+ }
+
+ struct NavigationMessage @0xe2517b083095fd4e {
+ type @0 :Int32;
+ svId @1 :Int32;
+ messageId @2 :Int32;
+ submessageId @3 :Int32;
+ data @4 :Data;
+ status @5 :Status;
+
+ enum Status @0xec1ff7996b35366f {
+ unknown @0;
+ parityPassed @1;
+ parityRebuilt @2;
+ }
+ }
+}
+
+struct QcomGnss @0xde94674b07ae51c1 {
+ logTs @0 :UInt64;
+ union {
+ measurementReport @1 :MeasurementReport;
+ clockReport @2 :ClockReport;
+ drMeasurementReport @3 :DrMeasurementReport;
+ drSvPoly @4 :DrSvPolyReport;
+ rawLog @5 :Data;
+ }
+
+ enum MeasurementSource @0xd71a12b6faada7ee {
+ gps @0;
+ glonass @1;
+ beidou @2;
+ }
+
+ enum SVObservationState @0xe81e829a0d6c83e9 {
+ idle @0;
+ search @1;
+ searchVerify @2;
+ bitEdge @3;
+ trackVerify @4;
+ track @5;
+ restart @6;
+ dpo @7;
+ glo10msBe @8;
+ glo10msAt @9;
+ }
+
+ struct MeasurementStatus @0xe501010e1bcae83b {
+ subMillisecondIsValid @0 :Bool;
+ subBitTimeIsKnown @1 :Bool;
+ satelliteTimeIsKnown @2 :Bool;
+ bitEdgeConfirmedFromSignal @3 :Bool;
+ measuredVelocity @4 :Bool;
+ fineOrCoarseVelocity @5 :Bool;
+ lockPointValid @6 :Bool;
+ lockPointPositive @7 :Bool;
+ lastUpdateFromDifference @8 :Bool;
+ lastUpdateFromVelocityDifference @9 :Bool;
+ strongIndicationOfCrossCorelation @10 :Bool;
+ tentativeMeasurement @11 :Bool;
+ measurementNotUsable @12 :Bool;
+ sirCheckIsNeeded @13 :Bool;
+ probationMode @14 :Bool;
+
+ glonassMeanderBitEdgeValid @15 :Bool;
+ glonassTimeMarkValid @16 :Bool;
+
+ gpsRoundRobinRxDiversity @17 :Bool;
+ gpsRxDiversity @18 :Bool;
+ gpsLowBandwidthRxDiversityCombined @19 :Bool;
+ gpsHighBandwidthNu4 @20 :Bool;
+ gpsHighBandwidthNu8 @21 :Bool;
+ gpsHighBandwidthUniform @22 :Bool;
+ multipathIndicator @23 :Bool;
+
+ imdJammingIndicator @24 :Bool;
+ lteB13TxJammingIndicator @25 :Bool;
+ freshMeasurementIndicator @26 :Bool;
+
+ multipathEstimateIsValid @27 :Bool;
+ directionIsValid @28 :Bool;
+ }
+
+ struct MeasurementReport @0xf580d7d86b7b8692 {
+ source @0 :MeasurementSource;
+
+ fCount @1 :UInt32;
+
+ gpsWeek @2 :UInt16;
+ glonassCycleNumber @3 :UInt8;
+ glonassNumberOfDays @4 :UInt16;
+
+ milliseconds @5 :UInt32;
+ timeBias @6 :Float32;
+ clockTimeUncertainty @7 :Float32;
+ clockFrequencyBias @8 :Float32;
+ clockFrequencyUncertainty @9 :Float32;
+
+ sv @10 :List(SV);
+
+ struct SV @0xf10c595ae7bb2c27 {
+ svId @0 :UInt8;
+ observationState @2 :SVObservationState;
+ observations @3 :UInt8;
+ goodObservations @4 :UInt8;
+ gpsParityErrorCount @5 :UInt16;
+ glonassFrequencyIndex @1 :Int8;
+ glonassHemmingErrorCount @6 :UInt8;
+ filterStages @7 :UInt8;
+ carrierNoise @8 :UInt16;
+ latency @9 :Int16;
+ predetectInterval @10 :UInt8;
+ postdetections @11 :UInt16;
+
+ unfilteredMeasurementIntegral @12 :UInt32;
+ unfilteredMeasurementFraction @13 :Float32;
+ unfilteredTimeUncertainty @14 :Float32;
+ unfilteredSpeed @15 :Float32;
+ unfilteredSpeedUncertainty @16 :Float32;
+ measurementStatus @17 :MeasurementStatus;
+ multipathEstimate @18 :UInt32;
+ azimuth @19 :Float32;
+ elevation @20 :Float32;
+ carrierPhaseCyclesIntegral @21 :Int32;
+ carrierPhaseCyclesFraction @22 :UInt16;
+ fineSpeed @23 :Float32;
+ fineSpeedUncertainty @24 :Float32;
+ cycleSlipCount @25 :UInt8;
+ }
+
+ }
+
+ struct ClockReport @0xca965e4add8f4f0b {
+ hasFCount @0 :Bool;
+ fCount @1 :UInt32;
+
+ hasGpsWeek @2 :Bool;
+ gpsWeek @3 :UInt16;
+ hasGpsMilliseconds @4 :Bool;
+ gpsMilliseconds @5 :UInt32;
+ gpsTimeBias @6 :Float32;
+ gpsClockTimeUncertainty @7 :Float32;
+ gpsClockSource @8 :UInt8;
+
+ hasGlonassYear @9 :Bool;
+ glonassYear @10 :UInt8;
+ hasGlonassDay @11 :Bool;
+ glonassDay @12 :UInt16;
+ hasGlonassMilliseconds @13 :Bool;
+ glonassMilliseconds @14 :UInt32;
+ glonassTimeBias @15 :Float32;
+ glonassClockTimeUncertainty @16 :Float32;
+ glonassClockSource @17 :UInt8;
+
+ bdsWeek @18 :UInt16;
+ bdsMilliseconds @19 :UInt32;
+ bdsTimeBias @20 :Float32;
+ bdsClockTimeUncertainty @21 :Float32;
+ bdsClockSource @22 :UInt8;
+
+ galWeek @23 :UInt16;
+ galMilliseconds @24 :UInt32;
+ galTimeBias @25 :Float32;
+ galClockTimeUncertainty @26 :Float32;
+ galClockSource @27 :UInt8;
+
+ clockFrequencyBias @28 :Float32;
+ clockFrequencyUncertainty @29 :Float32;
+ frequencySource @30 :UInt8;
+ gpsLeapSeconds @31 :UInt8;
+ gpsLeapSecondsUncertainty @32 :UInt8;
+ gpsLeapSecondsSource @33 :UInt8;
+
+ gpsToGlonassTimeBiasMilliseconds @34 :Float32;
+ gpsToGlonassTimeBiasMillisecondsUncertainty @35 :Float32;
+ gpsToBdsTimeBiasMilliseconds @36 :Float32;
+ gpsToBdsTimeBiasMillisecondsUncertainty @37 :Float32;
+ bdsToGloTimeBiasMilliseconds @38 :Float32;
+ bdsToGloTimeBiasMillisecondsUncertainty @39 :Float32;
+ gpsToGalTimeBiasMilliseconds @40 :Float32;
+ gpsToGalTimeBiasMillisecondsUncertainty @41 :Float32;
+ galToGloTimeBiasMilliseconds @42 :Float32;
+ galToGloTimeBiasMillisecondsUncertainty @43 :Float32;
+ galToBdsTimeBiasMilliseconds @44 :Float32;
+ galToBdsTimeBiasMillisecondsUncertainty @45 :Float32;
+
+ hasRtcTime @46 :Bool;
+ systemRtcTime @47 :UInt32;
+ fCountOffset @48 :UInt32;
+ lpmRtcCount @49 :UInt32;
+ clockResets @50 :UInt32;
+ }
+
+ struct DrMeasurementReport @0x8053c39445c6c75c {
+
+ reason @0 :UInt8;
+ seqNum @1 :UInt8;
+ seqMax @2 :UInt8;
+ rfLoss @3 :UInt16;
+
+ systemRtcValid @4 :Bool;
+ fCount @5 :UInt32;
+ clockResets @6 :UInt32;
+ systemRtcTime @7 :UInt64;
+
+ gpsLeapSeconds @8 :UInt8;
+ gpsLeapSecondsUncertainty @9 :UInt8;
+ gpsToGlonassTimeBiasMilliseconds @10 :Float32;
+ gpsToGlonassTimeBiasMillisecondsUncertainty @11 :Float32;
+
+ gpsWeek @12 :UInt16;
+ gpsMilliseconds @13 :UInt32;
+ gpsTimeBiasMs @14 :UInt32;
+ gpsClockTimeUncertaintyMs @15 :UInt32;
+ gpsClockSource @16 :UInt8;
+
+ glonassClockSource @17 :UInt8;
+ glonassYear @18 :UInt8;
+ glonassDay @19 :UInt16;
+ glonassMilliseconds @20 :UInt32;
+ glonassTimeBias @21 :Float32;
+ glonassClockTimeUncertainty @22 :Float32;
+
+ clockFrequencyBias @23 :Float32;
+ clockFrequencyUncertainty @24 :Float32;
+ frequencySource @25 :UInt8;
+
+ source @26 :MeasurementSource;
+
+ sv @27 :List(SV);
+
+ struct SV @0xf08b81df8cbf459c {
+ svId @0 :UInt8;
+ glonassFrequencyIndex @1 :Int8;
+ observationState @2 :SVObservationState;
+ observations @3 :UInt8;
+ goodObservations @4 :UInt8;
+ filterStages @5 :UInt8;
+ predetectInterval @6 :UInt8;
+ cycleSlipCount @7 :UInt8;
+ postdetections @8 :UInt16;
+
+ measurementStatus @9 :MeasurementStatus;
+
+ carrierNoise @10 :UInt16;
+ rfLoss @11 :UInt16;
+ latency @12 :Int16;
+
+ filteredMeasurementFraction @13 :Float32;
+ filteredMeasurementIntegral @14 :UInt32;
+ filteredTimeUncertainty @15 :Float32;
+ filteredSpeed @16 :Float32;
+ filteredSpeedUncertainty @17 :Float32;
+
+ unfilteredMeasurementFraction @18 :Float32;
+ unfilteredMeasurementIntegral @19 :UInt32;
+ unfilteredTimeUncertainty @20 :Float32;
+ unfilteredSpeed @21 :Float32;
+ unfilteredSpeedUncertainty @22 :Float32;
+
+ multipathEstimate @23 :UInt32;
+ azimuth @24 :Float32;
+ elevation @25 :Float32;
+ dopplerAcceleration @26 :Float32;
+ fineSpeed @27 :Float32;
+ fineSpeedUncertainty @28 :Float32;
+
+ carrierPhase @29 :Float64;
+ fCount @30 :UInt32;
+
+ parityErrorCount @31 :UInt16;
+ goodParity @32 :Bool;
+ }
+ }
+
+ struct DrSvPolyReport @0xb1fb80811a673270 {
+ svId @0 :UInt16;
+ frequencyIndex @1 :Int8;
+
+ hasPosition @2 :Bool;
+ hasIono @3 :Bool;
+ hasTropo @4 :Bool;
+ hasElevation @5 :Bool;
+ polyFromXtra @6 :Bool;
+ hasSbasIono @7 :Bool;
+
+ iode @8 :UInt16;
+ t0 @9 :Float64;
+ xyz0 @10 :List(Float64);
+ xyzN @11 :List(Float64);
+ other @12 :List(Float32);
+
+ positionUncertainty @13 :Float32;
+ ionoDelay @14 :Float32;
+ ionoDot @15 :Float32;
+ sbasIonoDelay @16 :Float32;
+ sbasIonoDot @17 :Float32;
+ tropoDelay @18 :Float32;
+ elevation @19 :Float32;
+ elevationDot @20 :Float32;
+ elevationUncertainty @21 :Float32;
+ velocityCoeff @22 :List(Float64);
+ }
+}
+
+struct LidarPts @0xe3d6685d4e9d8f7a {
+ r @0 :List(UInt16); # uint16 m*500.0
+ theta @1 :List(UInt16); # uint16 deg*100.0
+ reflect @2 :List(UInt8); # uint8 0-255
+
+ # For storing out of file.
+ idx @3 :UInt64;
+
+ # For storing in file
+ pkt @4 :Data;
+}
+
+
diff --git a/cereal/log.capnp b/cereal/log.capnp
index 11f49fa12..e717de08d 100644
--- a/cereal/log.capnp
+++ b/cereal/log.capnp
@@ -6,6 +6,7 @@ $Java.package("ai.comma.openpilot.cereal");
$Java.outerClassname("Log");
using Car = import "car.capnp";
+using Legacy = import "legacy.capnp";
@0xf3b1f17e25a4285b;
@@ -32,11 +33,7 @@ struct InitData {
gitBranch @11 :Text;
gitRemote @13 :Text;
- androidBuildInfo @5 :AndroidBuildInfo;
- androidSensors @6 :List(AndroidSensor);
androidProperties @16 :Map(Text, Text);
- chffrAndroidExtra @7 :ChffrAndroidExtra;
- iosBuildInfo @14 :IosBuildInfo;
pandaInfo @8 :PandaInfo;
@@ -53,6 +50,19 @@ struct InitData {
pc @5;
}
+ struct PandaInfo {
+ hasPanda @0 :Bool;
+ dongleId @1 :Text;
+ stVersion @2 :Text;
+ espVersion @3 :Text;
+ }
+
+ # ***** deprecated stuff *****
+ androidBuildInfo @5 :AndroidBuildInfo;
+ androidSensorsDEPRECATED @6 :List(AndroidSensor);
+ chffrAndroidExtraDEPRECATED @7 :ChffrAndroidExtra;
+ iosBuildInfoDEPRECATED @14 :IosBuildInfo;
+
struct AndroidBuildInfo {
board @0 :Text;
bootloader @1 :Text;
@@ -107,13 +117,6 @@ struct InitData {
osVersion @2 :Text;
deviceModel @3 :Text;
}
-
- struct PandaInfo {
- hasPanda @0 :Bool;
- dongleId @1 :Text;
- stVersion @2 :Text;
- espVersion @3 :Text;
- }
}
struct FrameData {
@@ -229,7 +232,7 @@ struct GpsLocationData {
speed @4 :Float32;
# Represents heading in degrees.
- bearing @5 :Float32;
+ bearingDeg @5 :Float32;
# Represents expected accuracy in meters. (presumably 1 sigma?)
accuracy @6 :Float32;
@@ -247,7 +250,7 @@ struct GpsLocationData {
verticalAccuracy @10 :Float32;
# Represents bearing accuracy in degrees. (presumably 1 sigma?)
- bearingAccuracy @11 :Float32;
+ bearingAccuracyDeg @11 :Float32;
# Represents velocity accuracy in m/s. (presumably 1 sigma?)
speedAccuracy @12 :Float32;
@@ -271,51 +274,41 @@ struct CanData {
src @3 :UInt8;
}
-struct ThermalData {
- # Deprecated
- cpu0DEPRECATED @0 :UInt16;
- cpu1DEPRECATED @1 :UInt16;
- cpu2DEPRECATED @2 :UInt16;
- cpu3DEPRECATED @3 :UInt16;
- memDEPRECATED @4 :UInt16;
- gpuDEPRECATED @5 :UInt16;
- batDEPRECATED @6 :UInt32;
- pa0DEPRECATED @21 :UInt16;
+struct DeviceState @0xa4d8b5af2aa492eb {
+ freeSpacePercent @7 :Float32;
+ memoryUsagePercent @19 :Int8;
+ cpuUsagePercent @20 :Int8;
+ usbOnline @12 :Bool;
+ networkType @22 :NetworkType;
+ offroadPowerUsageUwh @23 :UInt32;
+ networkStrength @24 :NetworkStrength;
+ carBatteryCapacityUwh @25 :UInt32;
- # not thermal
- freeSpace @7 :Float32;
+ fanSpeedPercentDesired @10 :UInt16;
+ started @11 :Bool;
+ startedMonoTime @13 :UInt64;
+
+ # power
batteryPercent @8 :Int16;
batteryStatus @9 :Text;
batteryCurrent @15 :Int32;
batteryVoltage @16 :Int32;
- usbOnline @12 :Bool;
- networkType @22 :NetworkType;
- offroadPowerUsage @23 :UInt32; # Power usage since going offroad in uWh
- networkStrength @24 :NetworkStrength;
- carBatteryCapacity @25 :UInt32; # Estimated remaining car battery capacity in uWh
-
- fanSpeed @10 :UInt16;
- started @11 :Bool;
- startedTs @13 :UInt64;
-
- thermalStatus @14 :ThermalStatus;
chargingError @17 :Bool;
chargingDisabled @18 :Bool;
- memUsedPercent @19 :Int8;
- cpuPerc @20 :Int8;
-
- cpu @26 :List(Float32);
- gpu @27 :List(Float32);
- mem @28 :Float32;
- bat @29 :Float32;
- ambient @30 :Float32;
+ # device thermals
+ cpuTempC @26 :List(Float32);
+ gpuTempC @27 :List(Float32);
+ memoryTempC @28 :Float32;
+ batteryTempC @29 :Float32;
+ ambientTempC @30 :Float32;
+ thermalStatus @14 :ThermalStatus;
enum ThermalStatus {
- green @0; # all processes run
- yellow @1; # critical processes run (kill uploader), engage still allowed
- red @2; # no engage, will disengage
- danger @3; # immediate process shutdown
+ green @0;
+ yellow @1;
+ red @2;
+ danger @3;
}
enum NetworkType {
@@ -334,22 +327,31 @@ struct ThermalData {
good @3;
great @4;
}
+
+ # deprecated
+ cpu0DEPRECATED @0 :UInt16;
+ cpu1DEPRECATED @1 :UInt16;
+ cpu2DEPRECATED @2 :UInt16;
+ cpu3DEPRECATED @3 :UInt16;
+ memDEPRECATED @4 :UInt16;
+ gpuDEPRECATED @5 :UInt16;
+ batDEPRECATED @6 :UInt32;
+ pa0DEPRECATED @21 :UInt16;
}
-struct HealthData {
+struct PandaState @0xa7649e2575e4591e {
# from can health
voltage @0 :UInt32;
current @1 :UInt32;
ignitionLine @2 :Bool;
controlsAllowed @3 :Bool;
gasInterceptorDetected @4 :Bool;
- startedSignalDetectedDeprecated @5 :Bool;
hasGps @6 :Bool;
canSendErrs @7 :UInt32;
canFwdErrs @8 :UInt32;
canRxErrs @19 :UInt32;
gmlanSendErrs @9 :UInt32;
- hwType @10 :HwType;
+ pandaType @10 :PandaType;
fanSpeedRpm @11 :UInt16;
usbPowerMode @12 :UsbPowerMode;
ignitionCan @13 :Bool;
@@ -391,7 +393,7 @@ struct HealthData {
# Update max fault type in boardd when adding faults
}
- enum HwType {
+ enum PandaType @0x8a58adf93e5b3751 {
unknown @0;
whitePanda @1;
greyPanda @2;
@@ -407,29 +409,16 @@ struct HealthData {
cdp @2;
dcp @3;
}
-}
-struct LiveUI {
- rearViewCam @0 :Bool;
- alertText1 @1 :Text;
- alertText2 @2 :Text;
- awarenessStatus @3 :Float32;
+ startedSignalDetectedDEPRECATED @5 :Bool;
}
struct RadarState @0x9a185389d6fdd05f {
canMonoTimes @10 :List(UInt64);
mdMonoTime @6 :UInt64;
- ftMonoTimeDEPRECATED @7 :UInt64;
- controlsStateMonoTime @11 :UInt64;
+ carStateMonoTime @11 :UInt64;
radarErrors @12 :List(Car.RadarData.Error);
- # all deprecated
- warpMatrixDEPRECATED @0 :List(Float32);
- angleOffsetDEPRECATED @1 :Float32;
- calStatusDEPRECATED @2 :Int8;
- calCycleDEPRECATED @8 :Int32;
- calPercDEPRECATED @9 :Int8;
-
leadOne @3 :LeadData;
leadTwo @4 :LeadData;
cumLagMs @5 :Float32;
@@ -440,7 +429,6 @@ struct RadarState @0x9a185389d6fdd05f {
vRel @2 :Float32;
aRel @3 :Float32;
vLead @4 :Float32;
- aLeadDEPRECATED @5 :Float32;
dPath @6 :Float32;
vLat @7 :Float32;
vLeadK @8 :Float32;
@@ -450,17 +438,20 @@ struct RadarState @0x9a185389d6fdd05f {
aLeadTau @12 :Float32;
modelProb @13 :Float32;
radar @14 :Bool;
+
+ aLeadDEPRECATED @5 :Float32;
}
+
+ # deprecated
+ ftMonoTimeDEPRECATED @7 :UInt64;
+ warpMatrixDEPRECATED @0 :List(Float32);
+ angleOffsetDEPRECATED @1 :Float32;
+ calStatusDEPRECATED @2 :Int8;
+ calCycleDEPRECATED @8 :Int32;
+ calPercDEPRECATED @9 :Int8;
}
struct LiveCalibrationData {
- # deprecated
- warpMatrix @0 :List(Float32);
-
- # camera_frame_from_model_frame
- warpMatrix2 @5 :List(Float32);
- warpMatrixBig @6 :List(Float32);
-
calStatus @1 :Int8;
calCycle @2 :Int32;
calPerc @3 :Int8;
@@ -472,6 +463,10 @@ struct LiveCalibrationData {
# the direction of travel vector in device frame
rpyCalib @7 :List(Float32);
rpyCalibSpread @8 :List(Float32);
+
+ warpMatrixDEPRECATED @0 :List(Float32);
+ warpMatrix2DEPRECATED @5 :List(Float32);
+ warpMatrixBigDEPRECATED @6 :List(Float32);
}
struct LiveTracks {
@@ -488,67 +483,38 @@ struct LiveTracks {
}
struct ControlsState @0x97ff69c53601abf1 {
- canMonoTimeDEPRECATED @16 :UInt64;
+ startMonoTime @48 :UInt64;
canMonoTimes @21 :List(UInt64);
- radarStateMonoTimeDEPRECATED @17 :UInt64;
- mdMonoTimeDEPRECATED @18 :UInt64;
- planMonoTime @28 :UInt64;
- pathPlanMonoTime @50 :UInt64;
+ longitudinalPlanMonoTime @28 :UInt64;
+ lateralPlanMonoTime @50 :UInt64;
state @31 :OpenpilotState;
- vEgo @0 :Float32;
- vEgoRaw @32 :Float32;
- aEgoDEPRECATED @1 :Float32;
+ enabled @19 :Bool;
+ active @36 :Bool;
+
longControlState @30 :LongControlState;
vPid @2 :Float32;
vTargetLead @3 :Float32;
+ vCruise @22 :Float32;
upAccelCmd @4 :Float32;
uiAccelCmd @5 :Float32;
ufAccelCmd @33 :Float32;
- yActualDEPRECATED @6 :Float32;
- yDesDEPRECATED @7 :Float32;
- upSteerDEPRECATED @8 :Float32;
- uiSteerDEPRECATED @9 :Float32;
- ufSteerDEPRECATED @34 :Float32;
- aTargetMinDEPRECATED @10 :Float32;
- aTargetMaxDEPRECATED @11 :Float32;
aTarget @35 :Float32;
- jerkFactor @12 :Float32;
- angleSteers @13 :Float32; # Steering angle in degrees.
- angleSteersDes @29 :Float32;
- curvature @37 :Float32; # path curvature from vehicle model
- hudLeadDEPRECATED @14 :Int32;
- cumLagMs @15 :Float32;
- startMonoTime @48 :UInt64;
- mapValid @49 :Bool;
+ steeringAngleDesiredDeg @29 :Float32;
+ curvature @37 :Float32; # path curvature from vehicle model
forceDecel @51 :Bool;
- enabled @19 :Bool;
- active @36 :Bool;
- steerOverride @20 :Bool;
-
- vCruise @22 :Float32;
-
- rearViewCam @23 :Bool;
+ # UI alerts
alertText1 @24 :Text;
alertText2 @25 :Text;
alertStatus @38 :AlertStatus;
alertSize @39 :AlertSize;
alertBlinkingRate @42 :Float32;
alertType @44 :Text;
- alertSoundDEPRECATED @45 :Text;
alertSound @56 :Car.CarControl.HUDControl.AudibleAlert;
- awarenessStatus @26 :Float32;
- angleModelBiasDEPRECATED @27 :Float32;
- gpsPlannerActive @40 :Bool;
engageable @41 :Bool; # can OP be engaged?
- driverMonitoringOn @43 :Bool;
- # maps
- vCurvature @46 :Float32;
- decelForTurn @47 :Bool;
-
- decelForModel @54 :Bool;
+ cumLagMs @15 :Float32;
canErrorCounter @57 :UInt32;
lateralControlState :union {
@@ -586,9 +552,9 @@ struct ControlsState @0x97ff69c53601abf1 {
struct LateralINDIState {
active @0 :Bool;
- steerAngle @1 :Float32;
- steerRate @2 :Float32;
- steerAccel @3 :Float32;
+ steeringAngleDeg @1 :Float32;
+ steeringRateDeg @2 :Float32;
+ steeringAccelDeg @3 :Float32;
rateSetPoint @4 :Float32;
accelSetPoint @5 :Float32;
accelError @6 :Float32;
@@ -600,8 +566,8 @@ struct ControlsState @0x97ff69c53601abf1 {
struct LateralPIDState {
active @0 :Bool;
- steerAngle @1 :Float32;
- steerRate @2 :Float32;
+ steeringAngleDeg @1 :Float32;
+ steeringRateDeg @2 :Float32;
angleError @3 :Float32;
p @4 :Float32;
i @5 :Float32;
@@ -612,88 +578,43 @@ struct ControlsState @0x97ff69c53601abf1 {
struct LateralLQRState {
active @0 :Bool;
- steerAngle @1 :Float32;
+ steeringAngleDeg @1 :Float32;
i @2 :Float32;
output @3 :Float32;
lqrOutput @4 :Float32;
saturated @5 :Bool;
}
+
+ # deprecated
+ vEgoDEPRECATED @0 :Float32;
+ vEgoRawDEPRECATED @32 :Float32;
+ aEgoDEPRECATED @1 :Float32;
+ canMonoTimeDEPRECATED @16 :UInt64;
+ radarStateMonoTimeDEPRECATED @17 :UInt64;
+ mdMonoTimeDEPRECATED @18 :UInt64;
+ yActualDEPRECATED @6 :Float32;
+ yDesDEPRECATED @7 :Float32;
+ upSteerDEPRECATED @8 :Float32;
+ uiSteerDEPRECATED @9 :Float32;
+ ufSteerDEPRECATED @34 :Float32;
+ aTargetMinDEPRECATED @10 :Float32;
+ aTargetMaxDEPRECATED @11 :Float32;
+ rearViewCamDEPRECATED @23 :Bool;
+ driverMonitoringOnDEPRECATED @43 :Bool;
+ hudLeadDEPRECATED @14 :Int32;
+ alertSoundDEPRECATED @45 :Text;
+ angleModelBiasDEPRECATED @27 :Float32;
+ gpsPlannerActiveDEPRECATED @40 :Bool;
+ decelForTurnDEPRECATED @47 :Bool;
+ decelForModelDEPRECATED @54 :Bool;
+ awarenessStatusDEPRECATED @26 :Float32;
+ angleSteersDEPRECATED @13 :Float32;
+ vCurvatureDEPRECATED @46 :Float32;
+ mapValidDEPRECATED @49 :Bool;
+ jerkFactorDEPRECATED @12 :Float32;
+ steerOverrideDEPRECATED @20 :Bool;
}
-struct LiveEventData {
- name @0 :Text;
- value @1 :Int32;
-}
-
-struct ModelData {
- frameId @0 :UInt32;
- frameAge @12 :UInt32;
- frameDropPerc @13 :Float32;
- timestampEof @9 :UInt64;
- modelExecutionTime @14 :Float32;
- gpuExecutionTime @16 :Float32;
- rawPred @15 :Data;
-
- path @1 :PathData;
- leftLane @2 :PathData;
- rightLane @3 :PathData;
- lead @4 :LeadData;
- freePath @6 :List(Float32);
-
- settings @5 :ModelSettings;
- leadFuture @7 :LeadData;
- speed @8 :List(Float32);
- meta @10 :MetaData;
- longitudinal @11 :LongitudinalData;
-
- struct PathData {
- points @0 :List(Float32);
- prob @1 :Float32;
- std @2 :Float32;
- stds @3 :List(Float32);
- poly @4 :List(Float32);
- validLen @5 :Float32;
- }
-
- struct LeadData {
- dist @0 :Float32;
- prob @1 :Float32;
- std @2 :Float32;
- relVel @3 :Float32;
- relVelStd @4 :Float32;
- relY @5 :Float32;
- relYStd @6 :Float32;
- relA @7 :Float32;
- relAStd @8 :Float32;
- }
-
- struct ModelSettings {
- bigBoxX @0 :UInt16;
- bigBoxY @1 :UInt16;
- bigBoxWidth @2 :UInt16;
- bigBoxHeight @3 :UInt16;
- boxProjection @4 :List(Float32);
- yuvCorrection @5 :List(Float32);
- inputTransform @6 :List(Float32);
- }
-
- struct MetaData {
- engagedProb @0 :Float32;
- desirePrediction @1 :List(Float32);
- brakeDisengageProb @2 :Float32;
- gasDisengageProb @3 :Float32;
- steerOverrideProb @4 :Float32;
- desireState @5 :List(Float32);
- }
-
- struct LongitudinalData {
- distances @2 :List(Float32);
- speeds @0 :List(Float32);
- accelerations @1 :List(Float32);
- }
-}
-
-
struct ModelDataV2 {
frameId @0 :UInt32;
frameAge @1 :UInt32;
@@ -701,21 +622,27 @@ struct ModelDataV2 {
timestampEof @3 :UInt64;
modelExecutionTime @15 :Float32;
gpuExecutionTime @17 :Float32;
- rawPred @16 :Data;
+ rawPredictions @16 :Data;
+ # predicted future position, orientation, etc..
position @4 :XYZTData;
orientation @5 :XYZTData;
velocity @6 :XYZTData;
orientationRate @7 :XYZTData;
+
+ # prediction lanelines and road edges
laneLines @8 :List(XYZTData);
laneLineProbs @9 :List(Float32);
laneLineStds @13 :List(Float32);
roadEdges @10 :List(XYZTData);
roadEdgeStds @14 :List(Float32);
+
+ # predicted lead cars
leads @11 :List(LeadDataV2);
meta @12 :MetaData;
+ # All SI units and in device frame
struct XYZTData {
x @0 :List(Float32);
y @1 :List(Float32);
@@ -727,8 +654,12 @@ struct ModelDataV2 {
}
struct LeadDataV2 {
- prob @0 :Float32;
+ prob @0 :Float32; # probability that car is your lead at time t
t @1 :Float32;
+
+ # x and y are relative position in device frame
+ # v is norm relative speed
+ # a is norm relative acceleration
xyva @2 :List(Float32);
xyvaStd @3 :List(Float32);
}
@@ -743,15 +674,6 @@ struct ModelDataV2 {
}
}
-
-struct CalibrationFeatures {
- frameId @0 :UInt32;
-
- p0 @1 :List(Float32);
- p1 @2 :List(Float32);
- status @3 :List(Int8);
-}
-
struct EncodeIndex {
# picture from camera
frameId @0 :UInt32;
@@ -787,64 +709,26 @@ struct AndroidLogEntry {
message @6 :Text;
}
-struct LogRotate {
- segmentNum @0 :Int32;
- path @1 :Text;
-}
-
-struct Plan {
+struct LongitudinalPlan @0xe00b5b3eba12876c {
mdMonoTime @9 :UInt64;
radarStateMonoTime @10 :UInt64;
- commIssue @31 :Bool;
- eventsDEPRECATED @13 :List(Car.CarEvent);
-
- # lateral, 3rd order polynomial
- lateralValidDEPRECATED @0 :Bool;
- dPolyDEPRECATED @1 :List(Float32);
- laneWidthDEPRECATED @11 :Float32;
-
- # longitudinal
- longitudinalValidDEPRECATED @2 :Bool;
vCruise @16 :Float32;
aCruise @17 :Float32;
vTarget @3 :Float32;
vTargetFuture @14 :Float32;
vMax @20 :Float32;
- aTargetMinDEPRECATED @4 :Float32;
- aTargetMaxDEPRECATED @5 :Float32;
aTarget @18 :Float32;
vStart @26 :Float32;
aStart @27 :Float32;
- jerkFactor @6 :Float32;
hasLead @7 :Bool;
- hasLeftLaneDEPRECATED @23 :Bool;
- hasRightLaneDEPRECATED @24 :Bool;
fcw @8 :Bool;
longitudinalPlanSource @15 :LongitudinalPlanSource;
- # gps trajectory in car frame
- gpsTrajectory @12 :GpsTrajectory;
-
- gpsPlannerActive @19 :Bool;
-
- # maps
- vCurvature @21 :Float32;
- decelForTurn @22 :Bool;
- mapValid @25 :Bool;
- radarValid @28 :Bool;
- radarCanError @30 :Bool;
-
processingDelay @29 :Float32;
-
- struct GpsTrajectory {
- x @0 :List(Float32);
- y @1 :List(Float32);
- }
-
enum LongitudinalPlanSource {
cruise @0;
mpc1 @1;
@@ -852,28 +736,44 @@ struct Plan {
mpc3 @3;
model @4;
}
+
+ # deprecated
+ jerkFactorDEPRECATED @6 :Float32;
+ hasLeftLaneDEPRECATED @23 :Bool;
+ hasRightLaneDEPRECATED @24 :Bool;
+ aTargetMinDEPRECATED @4 :Float32;
+ aTargetMaxDEPRECATED @5 :Float32;
+ lateralValidDEPRECATED @0 :Bool;
+ longitudinalValidDEPRECATED @2 :Bool;
+ dPolyDEPRECATED @1 :List(Float32);
+ laneWidthDEPRECATED @11 :Float32;
+ vCurvatureDEPRECATED @21 :Float32;
+ decelForTurnDEPRECATED @22 :Bool;
+ mapValidDEPRECATED @25 :Bool;
+ radarValidDEPRECATED @28 :Bool;
+ radarCanErrorDEPRECATED @30 :Bool;
+ commIssueDEPRECATED @31 :Bool;
+ eventsDEPRECATED @13 :List(Car.CarEvent);
+ gpsTrajectoryDEPRECATED @12 :GpsTrajectory;
+ gpsPlannerActiveDEPRECATED @19 :Bool;
+
+ struct GpsTrajectory {
+ x @0 :List(Float32);
+ y @1 :List(Float32);
+ }
}
-struct PathPlan {
+struct LateralPlan @0xe1e9318e2ae8b51e {
laneWidth @0 :Float32;
-
- dPoly @1 :List(Float32);
- cPoly @2 :List(Float32);
- cProb @3 :Float32;
- lPoly @4 :List(Float32);
lProb @5 :Float32;
- rPoly @6 :List(Float32);
rProb @7 :Float32;
+ dPathPoints @20 :List(Float32);
+ dProb @21 :Float32;
- angleSteers @8 :Float32; # deg
- rateSteers @13 :Float32; # deg/s
+ steeringAngleDeg @8 :Float32; # deg
+ steeringRateDeg @13 :Float32; # deg/s
mpcSolutionValid @9 :Bool;
- paramsValid @10 :Bool;
- modelValidDEPRECATED @12 :Bool;
- angleOffset @11 :Float32;
- sensorValid @14 :Bool;
- commIssue @15 :Bool;
- posenetValid @16 :Bool;
+ angleOffsetDeg @11 :Float32;
desire @17 :Desire;
laneChangeState @18 :LaneChangeState;
laneChangeDirection @19 :LaneChangeDirection;
@@ -900,6 +800,18 @@ struct PathPlan {
left @1;
right @2;
}
+
+ # deprecated
+ cProbDEPRECATED @3 :Float32;
+ dPolyDEPRECATED @1 :List(Float32);
+ cPolyDEPRECATED @2 :List(Float32);
+ lPolyDEPRECATED @4 :List(Float32);
+ rPolyDEPRECATED @6 :List(Float32);
+ modelValidDEPRECATED @12 :Bool;
+ commIssueDEPRECATED @15 :Bool;
+ posenetValidDEPRECATED @16 :Bool;
+ sensorValidDEPRECATED @14 :Bool;
+ paramsValidDEPRECATED @10 :Bool;
}
struct LiveLocationKalman {
@@ -954,591 +866,6 @@ struct LiveLocationKalman {
}
}
-struct LiveLocationData {
- status @0 :UInt8;
-
- # 3D fix
- lat @1 :Float64;
- lon @2 :Float64;
- alt @3 :Float32; # m
-
- # speed
- speed @4 :Float32; # m/s
-
- # NED velocity components
- vNED @5 :List(Float32);
-
- # roll, pitch, heading (x,y,z)
- roll @6 :Float32; # WRT to center of earth?
- pitch @7 :Float32; # WRT to center of earth?
- heading @8 :Float32; # WRT to north?
-
- # what are these?
- wanderAngle @9 :Float32;
- trackAngle @10 :Float32;
-
- # car frame -- https://upload.wikimedia.org/wikipedia/commons/f/f5/RPY_angles_of_cars.png
-
- # gyro, in car frame, deg/s
- gyro @11 :List(Float32);
-
- # accel, in car frame, m/s^2
- accel @12 :List(Float32);
-
- accuracy @13 :Accuracy;
-
- source @14 :SensorSource;
- # if we are fixing a location in the past
- fixMonoTime @15 :UInt64;
-
- gpsWeek @16 :Int32;
- timeOfWeek @17 :Float64;
-
- positionECEF @18 :List(Float64);
- poseQuatECEF @19 :List(Float32);
- pitchCalibration @20 :Float32;
- yawCalibration @21 :Float32;
- imuFrame @22 :List(Float32);
-
- struct Accuracy {
- pNEDError @0 :List(Float32);
- vNEDError @1 :List(Float32);
- rollError @2 :Float32;
- pitchError @3 :Float32;
- headingError @4 :Float32;
- ellipsoidSemiMajorError @5 :Float32;
- ellipsoidSemiMinorError @6 :Float32;
- ellipsoidOrientationError @7 :Float32;
- }
-
- enum SensorSource {
- applanix @0;
- kalman @1;
- orbslam @2;
- timing @3;
- dummy @4;
- }
-}
-
-struct EthernetPacket {
- pkt @0 :Data;
- ts @1 :Float32;
-}
-
-struct NavUpdate {
- isNavigating @0 :Bool;
- curSegment @1 :Int32;
- segments @2 :List(Segment);
-
- struct LatLng {
- lat @0 :Float64;
- lng @1 :Float64;
- }
-
- struct Segment {
- from @0 :LatLng;
- to @1 :LatLng;
- updateTime @2 :Int32;
- distance @3 :Int32;
- crossTime @4 :Int32;
- exitNo @5 :Int32;
- instruction @6 :Instruction;
-
- parts @7 :List(LatLng);
-
- enum Instruction {
- turnLeft @0;
- turnRight @1;
- keepLeft @2;
- keepRight @3;
- straight @4;
- roundaboutExitNumber @5;
- roundaboutExit @6;
- roundaboutTurnLeft @7;
- unkn8 @8;
- roundaboutStraight @9;
- unkn10 @10;
- roundaboutTurnRight @11;
- unkn12 @12;
- roundaboutUturn @13;
- unkn14 @14;
- arrive @15;
- exitLeft @16;
- exitRight @17;
- unkn18 @18;
- uturn @19;
- # ...
- }
- }
-}
-
-struct NavStatus {
- isNavigating @0 :Bool;
- currentAddress @1 :Address;
-
- struct Address {
- title @0 :Text;
- lat @1 :Float64;
- lng @2 :Float64;
- house @3 :Text;
- address @4 :Text;
- street @5 :Text;
- city @6 :Text;
- state @7 :Text;
- country @8 :Text;
- }
-}
-
-struct CellInfo {
- timestamp @0 :UInt64;
- repr @1 :Text; # android toString() for now
-}
-
-struct WifiScan {
- bssid @0 :Text;
- ssid @1 :Text;
- capabilities @2 :Text;
- frequency @3 :Int32;
- level @4 :Int32;
- timestamp @5 :Int64;
-
- centerFreq0 @6 :Int32;
- centerFreq1 @7 :Int32;
- channelWidth @8 :ChannelWidth;
- operatorFriendlyName @9 :Text;
- venueName @10 :Text;
- is80211mcResponder @11 :Bool;
- passpoint @12 :Bool;
-
- distanceCm @13 :Int32;
- distanceSdCm @14 :Int32;
-
- enum ChannelWidth {
- w20Mhz @0;
- w40Mhz @1;
- w80Mhz @2;
- w160Mhz @3;
- w80Plus80Mhz @4;
- }
-}
-
-struct AndroidGnss {
- union {
- measurements @0 :Measurements;
- navigationMessage @1 :NavigationMessage;
- }
-
- struct Measurements {
- clock @0 :Clock;
- measurements @1 :List(Measurement);
-
- struct Clock {
- timeNanos @0 :Int64;
- hardwareClockDiscontinuityCount @1 :Int32;
-
- hasTimeUncertaintyNanos @2 :Bool;
- timeUncertaintyNanos @3 :Float64;
-
- hasLeapSecond @4 :Bool;
- leapSecond @5 :Int32;
-
- hasFullBiasNanos @6 :Bool;
- fullBiasNanos @7 :Int64;
-
- hasBiasNanos @8 :Bool;
- biasNanos @9 :Float64;
-
- hasBiasUncertaintyNanos @10 :Bool;
- biasUncertaintyNanos @11 :Float64;
-
- hasDriftNanosPerSecond @12 :Bool;
- driftNanosPerSecond @13 :Float64;
-
- hasDriftUncertaintyNanosPerSecond @14 :Bool;
- driftUncertaintyNanosPerSecond @15 :Float64;
- }
-
- struct Measurement {
- svId @0 :Int32;
- constellation @1 :Constellation;
-
- timeOffsetNanos @2 :Float64;
- state @3 :Int32;
- receivedSvTimeNanos @4 :Int64;
- receivedSvTimeUncertaintyNanos @5 :Int64;
- cn0DbHz @6 :Float64;
- pseudorangeRateMetersPerSecond @7 :Float64;
- pseudorangeRateUncertaintyMetersPerSecond @8 :Float64;
- accumulatedDeltaRangeState @9 :Int32;
- accumulatedDeltaRangeMeters @10 :Float64;
- accumulatedDeltaRangeUncertaintyMeters @11 :Float64;
-
- hasCarrierFrequencyHz @12 :Bool;
- carrierFrequencyHz @13 :Float32;
- hasCarrierCycles @14 :Bool;
- carrierCycles @15 :Int64;
- hasCarrierPhase @16 :Bool;
- carrierPhase @17 :Float64;
- hasCarrierPhaseUncertainty @18 :Bool;
- carrierPhaseUncertainty @19 :Float64;
- hasSnrInDb @20 :Bool;
- snrInDb @21 :Float64;
-
- multipathIndicator @22 :MultipathIndicator;
-
- enum Constellation {
- unknown @0;
- gps @1;
- sbas @2;
- glonass @3;
- qzss @4;
- beidou @5;
- galileo @6;
- }
-
- enum State {
- unknown @0;
- codeLock @1;
- bitSync @2;
- subframeSync @3;
- towDecoded @4;
- msecAmbiguous @5;
- symbolSync @6;
- gloStringSync @7;
- gloTodDecoded @8;
- bdsD2BitSync @9;
- bdsD2SubframeSync @10;
- galE1bcCodeLock @11;
- galE1c2ndCodeLock @12;
- galE1bPageSync @13;
- sbasSync @14;
- }
-
- enum MultipathIndicator {
- unknown @0;
- detected @1;
- notDetected @2;
- }
- }
- }
-
- struct NavigationMessage {
- type @0 :Int32;
- svId @1 :Int32;
- messageId @2 :Int32;
- submessageId @3 :Int32;
- data @4 :Data;
- status @5 :Status;
-
- enum Status {
- unknown @0;
- parityPassed @1;
- parityRebuilt @2;
- }
- }
-}
-
-struct QcomGnss {
- logTs @0 :UInt64;
- union {
- measurementReport @1 :MeasurementReport;
- clockReport @2 :ClockReport;
- drMeasurementReport @3 :DrMeasurementReport;
- drSvPoly @4 :DrSvPolyReport;
- rawLog @5 :Data;
- }
-
- enum MeasurementSource @0xd71a12b6faada7ee {
- gps @0;
- glonass @1;
- beidou @2;
- }
-
- enum SVObservationState @0xe81e829a0d6c83e9 {
- idle @0;
- search @1;
- searchVerify @2;
- bitEdge @3;
- trackVerify @4;
- track @5;
- restart @6;
- dpo @7;
- glo10msBe @8;
- glo10msAt @9;
- }
-
- struct MeasurementStatus @0xe501010e1bcae83b {
- subMillisecondIsValid @0 :Bool;
- subBitTimeIsKnown @1 :Bool;
- satelliteTimeIsKnown @2 :Bool;
- bitEdgeConfirmedFromSignal @3 :Bool;
- measuredVelocity @4 :Bool;
- fineOrCoarseVelocity @5 :Bool;
- lockPointValid @6 :Bool;
- lockPointPositive @7 :Bool;
- lastUpdateFromDifference @8 :Bool;
- lastUpdateFromVelocityDifference @9 :Bool;
- strongIndicationOfCrossCorelation @10 :Bool;
- tentativeMeasurement @11 :Bool;
- measurementNotUsable @12 :Bool;
- sirCheckIsNeeded @13 :Bool;
- probationMode @14 :Bool;
-
- glonassMeanderBitEdgeValid @15 :Bool;
- glonassTimeMarkValid @16 :Bool;
-
- gpsRoundRobinRxDiversity @17 :Bool;
- gpsRxDiversity @18 :Bool;
- gpsLowBandwidthRxDiversityCombined @19 :Bool;
- gpsHighBandwidthNu4 @20 :Bool;
- gpsHighBandwidthNu8 @21 :Bool;
- gpsHighBandwidthUniform @22 :Bool;
- multipathIndicator @23 :Bool;
-
- imdJammingIndicator @24 :Bool;
- lteB13TxJammingIndicator @25 :Bool;
- freshMeasurementIndicator @26 :Bool;
-
- multipathEstimateIsValid @27 :Bool;
- directionIsValid @28 :Bool;
- }
-
- struct MeasurementReport {
- source @0 :MeasurementSource;
-
- fCount @1 :UInt32;
-
- gpsWeek @2 :UInt16;
- glonassCycleNumber @3 :UInt8;
- glonassNumberOfDays @4 :UInt16;
-
- milliseconds @5 :UInt32;
- timeBias @6 :Float32;
- clockTimeUncertainty @7 :Float32;
- clockFrequencyBias @8 :Float32;
- clockFrequencyUncertainty @9 :Float32;
-
- sv @10 :List(SV);
-
- struct SV {
- svId @0 :UInt8;
- observationState @2 :SVObservationState;
- observations @3 :UInt8;
- goodObservations @4 :UInt8;
- gpsParityErrorCount @5 :UInt16;
- glonassFrequencyIndex @1 :Int8;
- glonassHemmingErrorCount @6 :UInt8;
- filterStages @7 :UInt8;
- carrierNoise @8 :UInt16;
- latency @9 :Int16;
- predetectInterval @10 :UInt8;
- postdetections @11 :UInt16;
-
- unfilteredMeasurementIntegral @12 :UInt32;
- unfilteredMeasurementFraction @13 :Float32;
- unfilteredTimeUncertainty @14 :Float32;
- unfilteredSpeed @15 :Float32;
- unfilteredSpeedUncertainty @16 :Float32;
- measurementStatus @17 :MeasurementStatus;
- multipathEstimate @18 :UInt32;
- azimuth @19 :Float32;
- elevation @20 :Float32;
- carrierPhaseCyclesIntegral @21 :Int32;
- carrierPhaseCyclesFraction @22 :UInt16;
- fineSpeed @23 :Float32;
- fineSpeedUncertainty @24 :Float32;
- cycleSlipCount @25 :UInt8;
- }
-
- }
-
- struct ClockReport {
- hasFCount @0 :Bool;
- fCount @1 :UInt32;
-
- hasGpsWeek @2 :Bool;
- gpsWeek @3 :UInt16;
- hasGpsMilliseconds @4 :Bool;
- gpsMilliseconds @5 :UInt32;
- gpsTimeBias @6 :Float32;
- gpsClockTimeUncertainty @7 :Float32;
- gpsClockSource @8 :UInt8;
-
- hasGlonassYear @9 :Bool;
- glonassYear @10 :UInt8;
- hasGlonassDay @11 :Bool;
- glonassDay @12 :UInt16;
- hasGlonassMilliseconds @13 :Bool;
- glonassMilliseconds @14 :UInt32;
- glonassTimeBias @15 :Float32;
- glonassClockTimeUncertainty @16 :Float32;
- glonassClockSource @17 :UInt8;
-
- bdsWeek @18 :UInt16;
- bdsMilliseconds @19 :UInt32;
- bdsTimeBias @20 :Float32;
- bdsClockTimeUncertainty @21 :Float32;
- bdsClockSource @22 :UInt8;
-
- galWeek @23 :UInt16;
- galMilliseconds @24 :UInt32;
- galTimeBias @25 :Float32;
- galClockTimeUncertainty @26 :Float32;
- galClockSource @27 :UInt8;
-
- clockFrequencyBias @28 :Float32;
- clockFrequencyUncertainty @29 :Float32;
- frequencySource @30 :UInt8;
- gpsLeapSeconds @31 :UInt8;
- gpsLeapSecondsUncertainty @32 :UInt8;
- gpsLeapSecondsSource @33 :UInt8;
-
- gpsToGlonassTimeBiasMilliseconds @34 :Float32;
- gpsToGlonassTimeBiasMillisecondsUncertainty @35 :Float32;
- gpsToBdsTimeBiasMilliseconds @36 :Float32;
- gpsToBdsTimeBiasMillisecondsUncertainty @37 :Float32;
- bdsToGloTimeBiasMilliseconds @38 :Float32;
- bdsToGloTimeBiasMillisecondsUncertainty @39 :Float32;
- gpsToGalTimeBiasMilliseconds @40 :Float32;
- gpsToGalTimeBiasMillisecondsUncertainty @41 :Float32;
- galToGloTimeBiasMilliseconds @42 :Float32;
- galToGloTimeBiasMillisecondsUncertainty @43 :Float32;
- galToBdsTimeBiasMilliseconds @44 :Float32;
- galToBdsTimeBiasMillisecondsUncertainty @45 :Float32;
-
- hasRtcTime @46 :Bool;
- systemRtcTime @47 :UInt32;
- fCountOffset @48 :UInt32;
- lpmRtcCount @49 :UInt32;
- clockResets @50 :UInt32;
- }
-
- struct DrMeasurementReport {
-
- reason @0 :UInt8;
- seqNum @1 :UInt8;
- seqMax @2 :UInt8;
- rfLoss @3 :UInt16;
-
- systemRtcValid @4 :Bool;
- fCount @5 :UInt32;
- clockResets @6 :UInt32;
- systemRtcTime @7 :UInt64;
-
- gpsLeapSeconds @8 :UInt8;
- gpsLeapSecondsUncertainty @9 :UInt8;
- gpsToGlonassTimeBiasMilliseconds @10 :Float32;
- gpsToGlonassTimeBiasMillisecondsUncertainty @11 :Float32;
-
- gpsWeek @12 :UInt16;
- gpsMilliseconds @13 :UInt32;
- gpsTimeBiasMs @14 :UInt32;
- gpsClockTimeUncertaintyMs @15 :UInt32;
- gpsClockSource @16 :UInt8;
-
- glonassClockSource @17 :UInt8;
- glonassYear @18 :UInt8;
- glonassDay @19 :UInt16;
- glonassMilliseconds @20 :UInt32;
- glonassTimeBias @21 :Float32;
- glonassClockTimeUncertainty @22 :Float32;
-
- clockFrequencyBias @23 :Float32;
- clockFrequencyUncertainty @24 :Float32;
- frequencySource @25 :UInt8;
-
- source @26 :MeasurementSource;
-
- sv @27 :List(SV);
-
- struct SV {
- svId @0 :UInt8;
- glonassFrequencyIndex @1 :Int8;
- observationState @2 :SVObservationState;
- observations @3 :UInt8;
- goodObservations @4 :UInt8;
- filterStages @5 :UInt8;
- predetectInterval @6 :UInt8;
- cycleSlipCount @7 :UInt8;
- postdetections @8 :UInt16;
-
- measurementStatus @9 :MeasurementStatus;
-
- carrierNoise @10 :UInt16;
- rfLoss @11 :UInt16;
- latency @12 :Int16;
-
- filteredMeasurementFraction @13 :Float32;
- filteredMeasurementIntegral @14 :UInt32;
- filteredTimeUncertainty @15 :Float32;
- filteredSpeed @16 :Float32;
- filteredSpeedUncertainty @17 :Float32;
-
- unfilteredMeasurementFraction @18 :Float32;
- unfilteredMeasurementIntegral @19 :UInt32;
- unfilteredTimeUncertainty @20 :Float32;
- unfilteredSpeed @21 :Float32;
- unfilteredSpeedUncertainty @22 :Float32;
-
- multipathEstimate @23 :UInt32;
- azimuth @24 :Float32;
- elevation @25 :Float32;
- dopplerAcceleration @26 :Float32;
- fineSpeed @27 :Float32;
- fineSpeedUncertainty @28 :Float32;
-
- carrierPhase @29 :Float64;
- fCount @30 :UInt32;
-
- parityErrorCount @31 :UInt16;
- goodParity @32 :Bool;
- }
- }
-
- struct DrSvPolyReport {
- svId @0 :UInt16;
- frequencyIndex @1 :Int8;
-
- hasPosition @2 :Bool;
- hasIono @3 :Bool;
- hasTropo @4 :Bool;
- hasElevation @5 :Bool;
- polyFromXtra @6 :Bool;
- hasSbasIono @7 :Bool;
-
- iode @8 :UInt16;
- t0 @9 :Float64;
- xyz0 @10 :List(Float64);
- xyzN @11 :List(Float64);
- other @12 :List(Float32);
-
- positionUncertainty @13 :Float32;
- ionoDelay @14 :Float32;
- ionoDot @15 :Float32;
- sbasIonoDelay @16 :Float32;
- sbasIonoDot @17 :Float32;
- tropoDelay @18 :Float32;
- elevation @19 :Float32;
- elevationDot @20 :Float32;
- elevationUncertainty @21 :Float32;
-
- velocityCoeff @22 :List(Float64);
-
- }
-}
-
-struct LidarPts {
- r @0 :List(UInt16); # uint16 m*500.0
- theta @1 :List(UInt16); # uint16 deg*100.0
- reflect @2 :List(UInt8); # uint8 0-255
-
- # For storing out of file.
- idx @3 :UInt64;
-
- # For storing in file
- pkt @4 :Data;
-}
-
struct ProcLog {
cpuTimes @0 :List(CPUTimes);
mem @1 :Mem;
@@ -1589,7 +916,6 @@ struct ProcLog {
inactive @6 :UInt64;
shared @7 :UInt64;
}
-
}
struct UbloxGnss {
@@ -1598,6 +924,7 @@ struct UbloxGnss {
ephemeris @1 :Ephemeris;
ionoData @2 :IonoData;
hwStatus @3 :HwStatus;
+ hwStatus2 @4 :HwStatus2;
}
struct MeasurementReport {
@@ -1743,6 +1070,24 @@ struct UbloxGnss {
dontknow @2;
}
}
+
+ struct HwStatus2 {
+ ofsI @0 :Int8;
+ magI @1 :UInt8;
+ ofsQ @2 :Int8;
+ magQ @3 :UInt8;
+ cfgSource @4 :ConfigSource;
+ lowLevCfg @5 :UInt32;
+ postStatus @6 :UInt32;
+
+ enum ConfigSource {
+ undefined @0;
+ rom @1;
+ otp @2;
+ configpins @3;
+ flash @4;
+ }
+ }
}
struct Clocks {
@@ -1777,105 +1122,6 @@ struct LiveLongitudinalMpcData {
cost @10 :Float64;
}
-
-struct ECEFPointDEPRECATED @0xe10e21168db0c7f7 {
- x @0 :Float32;
- y @1 :Float32;
- z @2 :Float32;
-}
-
-struct ECEFPoint @0xc25bbbd524983447 {
- x @0 :Float64;
- y @1 :Float64;
- z @2 :Float64;
-}
-
-struct GPSPlannerPoints {
- curPosDEPRECATED @0 :ECEFPointDEPRECATED;
- pointsDEPRECATED @1 :List(ECEFPointDEPRECATED);
- curPos @6 :ECEFPoint;
- points @7 :List(ECEFPoint);
- valid @2 :Bool;
- trackName @3 :Text;
- speedLimit @4 :Float32;
- accelTarget @5 :Float32;
-}
-
-struct GPSPlannerPlan {
- valid @0 :Bool;
- poly @1 :List(Float32);
- trackName @2 :Text;
- speed @3 :Float32;
- acceleration @4 :Float32;
- pointsDEPRECATED @5 :List(ECEFPointDEPRECATED);
- points @6 :List(ECEFPoint);
- xLookahead @7 :Float32;
-}
-
-struct TrafficEvent @0xacfa74a094e62626 {
- type @0 :Type;
- distance @1 :Float32;
- action @2 :Action;
- resuming @3 :Bool;
-
- enum Type {
- stopSign @0;
- lightRed @1;
- lightYellow @2;
- lightGreen @3;
- stopLight @4;
- }
-
- enum Action {
- none @0;
- yield @1;
- stop @2;
- resumeReady @3;
- }
-
-}
-
-struct OrbslamCorrection {
- correctionMonoTime @0 :UInt64;
- prePositionECEF @1 :List(Float64);
- postPositionECEF @2 :List(Float64);
- prePoseQuatECEF @3 :List(Float32);
- postPoseQuatECEF @4 :List(Float32);
- numInliers @5 :UInt32;
-}
-
-struct OrbObservation {
- observationMonoTime @0 :UInt64;
- normalizedCoordinates @1 :List(Float32);
- locationECEF @2 :List(Float64);
- matchDistance @3: UInt32;
-}
-
-struct UiNavigationEvent {
- type @0: Type;
- status @1: Status;
- distanceTo @2: Float32;
- endRoadPointDEPRECATED @3: ECEFPointDEPRECATED;
- endRoadPoint @4: ECEFPoint;
-
- enum Type {
- none @0;
- laneChangeLeft @1;
- laneChangeRight @2;
- mergeLeft @3;
- mergeRight @4;
- turnLeft @5;
- turnRight @6;
- }
-
- enum Status {
- none @0;
- passive @1;
- approaching @2;
- active @3;
- }
-}
-
struct UiLayoutState {
activeApp @0 :App;
sidebarCollapsed @1 :Bool;
@@ -1897,70 +1143,12 @@ struct Joystick {
buttons @1: List(Bool);
}
-struct OrbOdometry {
- # timing first
- startMonoTime @0 :UInt64;
- endMonoTime @1 :UInt64;
-
- # fundamental matrix and error
- f @2: List(Float64);
- err @3: Float64;
-
- # number of inlier points
- inliers @4: Int32;
-
- # for debug only
- # indexed by endMonoTime features
- # value is startMonoTime feature match
- # -1 if no match
- matches @5: List(Int16);
-}
-
-struct OrbFeatures {
- timestampEof @0 :UInt64;
- # transposed arrays of normalized image coordinates
- # len(xs) == len(ys) == len(descriptors) * 32
- xs @1 :List(Float32);
- ys @2 :List(Float32);
- descriptors @3 :Data;
- octaves @4 :List(Int8);
-
- # match index to last OrbFeatures
- # -1 if no match
- timestampLastEof @5 :UInt64;
- matches @6: List(Int16);
-}
-
-struct OrbFeaturesSummary {
- timestampEof @0 :UInt64;
- timestampLastEof @1 :UInt64;
-
- featureCount @2 :UInt16;
- matchCount @3 :UInt16;
- computeNs @4 :UInt64;
-}
-
-struct OrbKeyFrame {
- # this is a globally unique id for the KeyFrame
- id @0: UInt64;
-
- # this is the location of the KeyFrame
- pos @1: ECEFPoint;
-
- # these are the features in the world
- # len(dpos) == len(descriptors) * 32
- dpos @2 :List(ECEFPoint);
- descriptors @3 :Data;
-}
-
struct DriverState {
frameId @0 :UInt32;
modelExecutionTime @14 :Float32;
dspExecutionTime @16 :Float32;
- rawPred @15 :Data;
+ rawPredictions @15 :Data;
- descriptorDEPRECATED @1 :List(Float32);
- stdDEPRECATED @2 :Float32;
faceOrientation @3 :List(Float32);
facePosition @4 :List(Float32);
faceProb @5 :Float32;
@@ -1968,19 +1156,24 @@ struct DriverState {
rightEyeProb @7 :Float32;
leftBlinkProb @8 :Float32;
rightBlinkProb @9 :Float32;
- irPwrDEPRECATED @10 :Float32;
faceOrientationStd @11 :List(Float32);
facePositionStd @12 :List(Float32);
- sgProb @13 :Float32;
+ sunglassesProb @13 :Float32;
+ poorVision @17 :Float32;
+ partialFace @18 :Float32;
+ distractedPose @19 :Float32;
+ distractedEyes @20 :Float32;
+
+ irPwrDEPRECATED @10 :Float32;
+ descriptorDEPRECATED @1 :List(Float32);
+ stdDEPRECATED @2 :Float32;
}
-struct DMonitoringState {
- # TODO: deprecate old fields in controlsState
+struct DriverMonitoringState @0xb83cda094a1da284 {
events @0 :List(Car.CarEvent);
faceDetected @1 :Bool;
isDistracted @2 :Bool;
awarenessStatus @3 :Float32;
- isRHD @4 :Bool;
posePitchOffset @6 :Float32;
posePitchValidCount @7 :UInt32;
poseYawOffset @8 :Float32;
@@ -1990,8 +1183,10 @@ struct DMonitoringState {
awarenessPassive @12 :Float32;
isLowStd @13 :Bool;
hiStdCount @14 :UInt32;
- isPreview @15 :Bool;
+ isActiveMode @16 :Bool;
+ isRHDDEPRECATED @4 :Bool;
+ isPreviewDEPRECATED @15 :Bool;
rhdCheckedDEPRECATED @5 :Bool;
}
@@ -2005,8 +1200,8 @@ struct Boot {
struct LiveParametersData {
valid @0 :Bool;
gyroBias @1 :Float32;
- angleOffset @2 :Float32;
- angleOffsetAverage @3 :Float32;
+ angleOffsetDeg @2 :Float32;
+ angleOffsetAverageDeg @3 :Float32;
stiffnessFactor @4 :Float32;
steerRatio @5 :Float32;
sensorValid @6 :Bool;
@@ -2015,7 +1210,7 @@ struct LiveParametersData {
posenetValid @9 :Bool;
}
-struct LiveMapData {
+struct LiveMapDataDEPRECATED {
speedLimitValid @0 :Bool;
speedLimit @1 :Float32;
speedAdvisoryValid @12 :Bool;
@@ -2044,13 +1239,6 @@ struct CameraOdometry {
rotStd @3 :List(Float32); # std rad/s in device frame
}
-struct KalmanOdometry {
- trans @0 :List(Float32); # m/s in device frame
- rot @1 :List(Float32); # rad/s in device frame
- transStd @2 :List(Float32); # std m/s in device frame
- rotStd @3 :List(Float32); # std rad/s in device frame
-}
-
struct Sentinel {
enum SentinelType {
endOfSegment @0;
@@ -2061,87 +1249,112 @@ struct Sentinel {
type @0 :SentinelType;
}
+struct ManagerState {
+ processes @0 :List(ProcessState);
+
+ struct ProcessState {
+ name @0 :Text;
+ pid @1 :Int32;
+ running @2 :Bool;
+ exitCode @3 :Int32;
+ }
+}
+
struct Event {
- # in nanoseconds?
- logMonoTime @0 :UInt64;
+ logMonoTime @0 :UInt64; # nanoseconds
valid @67 :Bool = true;
union {
+ # *********** log metadata ***********
initData @1 :InitData;
- frame @2 :FrameData;
+ sentinel @73 :Sentinel;
+
+ # *********** bootlog ***********
+ boot @60 :Boot;
+
+ # ********** openpilot daemon msgs **********
gpsNMEA @3 :GPSNMEAData;
- sensorEventDEPRECATED @4 :SensorEventData;
can @5 :List(CanData);
- thermal @6 :ThermalData;
controlsState @7 :ControlsState;
- liveEventDEPRECATED @8 :List(LiveEventData);
- model @9 :ModelData;
- features @10 :CalibrationFeatures;
sensorEvents @11 :List(SensorEventData);
- health @12 :HealthData;
+ pandaState @12 :PandaState;
radarState @13 :RadarState;
- liveUIDEPRECATED @14 :LiveUI;
- encodeIdx @15 :EncodeIndex;
liveTracks @16 :List(LiveTracks);
sendcan @17 :List(CanData);
- logMessage @18 :Text;
liveCalibration @19 :LiveCalibrationData;
- androidLog @20 :AndroidLogEntry;
gpsLocation @21 :GpsLocationData;
carState @22 :Car.CarState;
carControl @23 :Car.CarControl;
- plan @24 :Plan;
- liveLocation @25 :LiveLocationData;
- ethernetData @26 :List(EthernetPacket);
- navUpdate @27 :NavUpdate;
- cellInfo @28 :List(CellInfo);
- wifiScan @29 :List(WifiScan);
- androidGnss @30 :AndroidGnss;
- qcomGnss @31 :QcomGnss;
- lidarPts @32 :LidarPts;
- procLog @33 :ProcLog;
+ longitudinalPlan @24 :LongitudinalPlan;
+ lateralPlan @64 :LateralPlan;
ubloxGnss @34 :UbloxGnss;
- clocks @35 :Clocks;
liveMpc @36 :LiveMpcData;
liveLongitudinalMpc @37 :LiveLongitudinalMpcData;
- navStatus @38 :NavStatus;
ubloxRaw @39 :Data;
- gpsPlannerPoints @40 :GPSPlannerPoints;
- gpsPlannerPlan @41 :GPSPlannerPlan;
- applanixRaw @42 :Data;
- trafficEvents @43 :List(TrafficEvent);
- liveLocationTiming @44 :LiveLocationData;
- orbslamCorrectionDEPRECATED @45 :OrbslamCorrection;
- liveLocationCorrected @46 :LiveLocationData;
- orbObservation @47 :List(OrbObservation);
gpsLocationExternal @48 :GpsLocationData;
- location @49 :LiveLocationData;
- uiNavigationEvent @50 :UiNavigationEvent;
- liveLocationKalmanDEPRECATED @51 :LiveLocationData;
- testJoystick @52 :Joystick;
- orbOdometry @53 :OrbOdometry;
- orbFeatures @54 :OrbFeatures;
- applanixLocation @55 :LiveLocationData;
- orbKeyFrame @56 :OrbKeyFrame;
uiLayoutState @57 :UiLayoutState;
- orbFeaturesSummary @58 :OrbFeaturesSummary;
driverState @59 :DriverState;
- boot @60 :Boot;
liveParameters @61 :LiveParametersData;
- liveMapData @62 :LiveMapData;
cameraOdometry @63 :CameraOdometry;
- pathPlan @64 :PathPlan;
- kalmanOdometry @65 :KalmanOdometry;
thumbnail @66: Thumbnail;
carEvents @68: List(Car.CarEvent);
carParams @69: Car.CarParams;
- frontFrame @70: FrameData; # driver facing camera
- dMonitoringState @71: DMonitoringState;
+ driverMonitoringState @71: DriverMonitoringState;
liveLocationKalman @72 :LiveLocationKalman;
- sentinel @73 :Sentinel;
- wideFrame @74: FrameData;
modelV2 @75 :ModelDataV2;
- frontEncodeIdx @76 :EncodeIndex; # driver facing camera
- wideEncodeIdx @77 :EncodeIndex;
+
+ # camera stuff, each camera state has a matching encode idx
+ roadCameraState @2 :FrameData;
+ driverCameraState @70: FrameData;
+ wideRoadCameraState @74: FrameData;
+ roadEncodeIdx @15 :EncodeIndex;
+ driverEncodeIdx @76 :EncodeIndex;
+ wideRoadEncodeIdx @77 :EncodeIndex;
+
+ # systems stuff
+ androidLog @20 :AndroidLogEntry;
+ managerState @78 :ManagerState;
+ procLog @33 :ProcLog;
+ clocks @35 :Clocks;
+ deviceState @6 :DeviceState;
+ logMessage @18 :Text;
+
+
+ # *********** debug ***********
+ testJoystick @52 :Joystick;
+
+ # *********** legacy + deprecated ***********
+ model @9 :Legacy.ModelData; # TODO: rename modelV2 and mark this as deprecated
+ liveLocationKalmanDEPRECATED @51 :Legacy.LiveLocationData;
+ orbslamCorrectionDEPRECATED @45 :Legacy.OrbslamCorrection;
+ liveUIDEPRECATED @14 :Legacy.LiveUI;
+ sensorEventDEPRECATED @4 :SensorEventData;
+ liveEventDEPRECATED @8 :List(Legacy.LiveEventData);
+ liveLocationDEPRECATED @25 :Legacy.LiveLocationData;
+ ethernetDataDEPRECATED @26 :List(Legacy.EthernetPacket);
+ cellInfoDEPRECATED @28 :List(Legacy.CellInfo);
+ wifiScanDEPRECATED @29 :List(Legacy.WifiScan);
+ uiNavigationEventDEPRECATED @50 :Legacy.UiNavigationEvent;
+ liveMapDataDEPRECATED @62 :LiveMapDataDEPRECATED;
+ gpsPlannerPointsDEPRECATED @40 :Legacy.GPSPlannerPoints;
+ gpsPlannerPlanDEPRECATED @41 :Legacy.GPSPlannerPlan;
+ applanixRawDEPRECATED @42 :Data;
+ androidGnssDEPRECATED @30 :Legacy.AndroidGnss;
+ qcomGnssDEPRECATD @31 :Legacy.QcomGnss;
+ lidarPtsDEPRECATED @32 :Legacy.LidarPts;
+ navStatusDEPRECATED @38 :Legacy.NavStatus;
+ trafficEventsDEPRECATED @43 :List(Legacy.TrafficEvent);
+ liveLocationTimingDEPRECATED @44 :Legacy.LiveLocationData;
+ liveLocationCorrectedDEPRECATED @46 :Legacy.LiveLocationData;
+ navUpdateDEPRECATED @27 :Legacy.NavUpdate;
+ orbObservationDEPRECATED @47 :List(Legacy.OrbObservation);
+ locationDEPRECATED @49 :Legacy.LiveLocationData;
+ orbOdometryDEPRECATED @53 :Legacy.OrbOdometry;
+ orbFeaturesDEPRECATED @54 :Legacy.OrbFeatures;
+ applanixLocationDEPRECATED @55 :Legacy.LiveLocationData;
+ orbKeyFrameDEPRECATED @56 :Legacy.OrbKeyFrame;
+ orbFeaturesSummaryDEPRECATED @58 :Legacy.OrbFeaturesSummary;
+ featuresDEPRECATED @10 :Legacy.CalibrationFeatures;
+ kalmanOdometryDEPRECATED @65 :Legacy.KalmanOdometry;
}
}
diff --git a/cereal/messaging/impl_msgq.cc b/cereal/messaging/impl_msgq.cc
index 7da9a227c..e211d6abb 100644
--- a/cereal/messaging/impl_msgq.cc
+++ b/cereal/messaging/impl_msgq.cc
@@ -5,9 +5,10 @@
#include
#include
-
+#include "services.h"
#include "impl_msgq.hpp"
+
volatile sig_atomic_t msgq_do_exit = 0;
void sig_handler(int signal) {
@@ -15,14 +16,21 @@ void sig_handler(int signal) {
msgq_do_exit = 1;
}
+static bool service_exists(std::string path){
+ for (const auto& it : services) {
+ if (it.name == path) {
+ return true;
+ }
+ }
+ return false;
+}
+
static size_t get_size(std::string endpoint){
size_t sz = DEFAULT_SEGMENT_SIZE;
-#if !defined(QCOM) && !defined(QCOM2)
- if (endpoint == "frame" || endpoint == "frontFrame" || endpoint == "wideFrame"){
+ if (endpoint == "roadCameraState" || endpoint == "driverCameraState" || endpoint == "wideRoadCameraState"){
sz *= 10;
}
-#endif
return sz;
}
@@ -61,10 +69,14 @@ MSGQMessage::~MSGQMessage() {
this->close();
}
-int MSGQSubSocket::connect(Context *context, std::string endpoint, std::string address, bool conflate){
+int MSGQSubSocket::connect(Context *context, std::string endpoint, std::string address, bool conflate, bool check_endpoint){
assert(context);
assert(address == "127.0.0.1");
+ if (check_endpoint && !service_exists(std::string(endpoint))){
+ std::cout << "Warning, " << std::string(endpoint) << " is not in service list." << std::endl;
+ }
+
q = new msgq_queue_t;
int r = msgq_new_queue(q, endpoint.c_str(), get_size(endpoint));
if (r != 0){
@@ -150,9 +162,13 @@ MSGQSubSocket::~MSGQSubSocket(){
}
}
-int MSGQPubSocket::connect(Context *context, std::string endpoint){
+int MSGQPubSocket::connect(Context *context, std::string endpoint, bool check_endpoint){
assert(context);
+ if (check_endpoint && !service_exists(std::string(endpoint))){
+ std::cout << "Warning, " << std::string(endpoint) << " is not in service list." << std::endl;
+ }
+
q = new msgq_queue_t;
int r = msgq_new_queue(q, endpoint.c_str(), get_size(endpoint));
if (r != 0){
diff --git a/cereal/messaging/impl_msgq.hpp b/cereal/messaging/impl_msgq.hpp
index 98e680945..e89994852 100644
--- a/cereal/messaging/impl_msgq.hpp
+++ b/cereal/messaging/impl_msgq.hpp
@@ -34,7 +34,7 @@ private:
msgq_queue_t * q = NULL;
int timeout;
public:
- int connect(Context *context, std::string endpoint, std::string address, bool conflate=false);
+ int connect(Context *context, std::string endpoint, std::string address, bool conflate=false, bool check_endpoint=true);
void setTimeout(int timeout);
void * getRawSocket() {return (void*)q;}
Message *receive(bool non_blocking=false);
@@ -45,7 +45,7 @@ class MSGQPubSocket : public PubSocket {
private:
msgq_queue_t * q = NULL;
public:
- int connect(Context *context, std::string endpoint);
+ int connect(Context *context, std::string endpoint, bool check_endpoint=true);
int sendMessage(Message *message);
int send(char *data, size_t size);
~MSGQPubSocket();
diff --git a/cereal/messaging/impl_zmq.cc b/cereal/messaging/impl_zmq.cc
index 195124de6..605165fcf 100644
--- a/cereal/messaging/impl_zmq.cc
+++ b/cereal/messaging/impl_zmq.cc
@@ -54,7 +54,7 @@ ZMQMessage::~ZMQMessage() {
}
-int ZMQSubSocket::connect(Context *context, std::string endpoint, std::string address, bool conflate){
+int ZMQSubSocket::connect(Context *context, std::string endpoint, std::string address, bool conflate, bool check_endpoint){
sock = zmq_socket(context->getRawContext(), ZMQ_SUB);
if (sock == NULL){
return -1;
@@ -71,7 +71,11 @@ int ZMQSubSocket::connect(Context *context, std::string endpoint, std::string ad
zmq_setsockopt(sock, ZMQ_RECONNECT_IVL_MAX, &reconnect_ivl, sizeof(reconnect_ivl));
full_endpoint = "tcp://" + address + ":";
- full_endpoint += std::to_string(get_port(endpoint));
+ if (check_endpoint){
+ full_endpoint += std::to_string(get_port(endpoint));
+ } else {
+ full_endpoint += endpoint;
+ }
return zmq_connect(sock, full_endpoint.c_str());
}
@@ -103,14 +107,18 @@ ZMQSubSocket::~ZMQSubSocket(){
zmq_close(sock);
}
-int ZMQPubSocket::connect(Context *context, std::string endpoint){
+int ZMQPubSocket::connect(Context *context, std::string endpoint, bool check_endpoint){
sock = zmq_socket(context->getRawContext(), ZMQ_PUB);
if (sock == NULL){
return -1;
}
full_endpoint = "tcp://*:";
- full_endpoint += std::to_string(get_port(endpoint));
+ if (check_endpoint){
+ full_endpoint += std::to_string(get_port(endpoint));
+ } else {
+ full_endpoint += endpoint;
+ }
return zmq_bind(sock, full_endpoint.c_str());
}
diff --git a/cereal/messaging/impl_zmq.hpp b/cereal/messaging/impl_zmq.hpp
index bfa9b74cd..f9f6deedb 100644
--- a/cereal/messaging/impl_zmq.hpp
+++ b/cereal/messaging/impl_zmq.hpp
@@ -32,7 +32,7 @@ private:
void * sock;
std::string full_endpoint;
public:
- int connect(Context *context, std::string endpoint, std::string address, bool conflate=false);
+ int connect(Context *context, std::string endpoint, std::string address, bool conflate=false, bool check_endpoint=true);
void setTimeout(int timeout);
void * getRawSocket() {return sock;}
Message *receive(bool non_blocking=false);
@@ -44,7 +44,7 @@ private:
void * sock;
std::string full_endpoint;
public:
- int connect(Context *context, std::string endpoint);
+ int connect(Context *context, std::string endpoint, bool check_endpoint=true);
int sendMessage(Message *message);
int send(char *data, size_t size);
~ZMQPubSocket();
diff --git a/cereal/messaging/messaging.cc b/cereal/messaging/messaging.cc
index 9e2ae409d..06bc66ae1 100644
--- a/cereal/messaging/messaging.cc
+++ b/cereal/messaging/messaging.cc
@@ -8,9 +8,13 @@ const bool MUST_USE_ZMQ = true;
const bool MUST_USE_ZMQ = false;
#endif
+bool messaging_use_zmq(){
+ return std::getenv("ZMQ") || MUST_USE_ZMQ;
+}
+
Context * Context::create(){
Context * c;
- if (std::getenv("ZMQ") || MUST_USE_ZMQ){
+ if (messaging_use_zmq()){
c = new ZMQContext();
} else {
c = new MSGQContext();
@@ -20,7 +24,7 @@ Context * Context::create(){
SubSocket * SubSocket::create(){
SubSocket * s;
- if (std::getenv("ZMQ") || MUST_USE_ZMQ){
+ if (messaging_use_zmq()){
s = new ZMQSubSocket();
} else {
s = new MSGQSubSocket();
@@ -28,33 +32,9 @@ SubSocket * SubSocket::create(){
return s;
}
-SubSocket * SubSocket::create(Context * context, std::string endpoint){
+SubSocket * SubSocket::create(Context * context, std::string endpoint, std::string address, bool conflate, bool check_endpoint){
SubSocket *s = SubSocket::create();
- int r = s->connect(context, endpoint, "127.0.0.1");
-
- if (r == 0) {
- return s;
- } else {
- delete s;
- return NULL;
- }
-}
-
-SubSocket * SubSocket::create(Context * context, std::string endpoint, std::string address){
- SubSocket *s = SubSocket::create();
- int r = s->connect(context, endpoint, address);
-
- if (r == 0) {
- return s;
- } else {
- delete s;
- return NULL;
- }
-}
-
-SubSocket * SubSocket::create(Context * context, std::string endpoint, std::string address, bool conflate){
- SubSocket *s = SubSocket::create();
- int r = s->connect(context, endpoint, address, conflate);
+ int r = s->connect(context, endpoint, address, conflate, check_endpoint);
if (r == 0) {
return s;
@@ -66,7 +46,7 @@ SubSocket * SubSocket::create(Context * context, std::string endpoint, std::stri
PubSocket * PubSocket::create(){
PubSocket * s;
- if (std::getenv("ZMQ") || MUST_USE_ZMQ){
+ if (messaging_use_zmq()){
s = new ZMQPubSocket();
} else {
s = new MSGQPubSocket();
@@ -74,9 +54,9 @@ PubSocket * PubSocket::create(){
return s;
}
-PubSocket * PubSocket::create(Context * context, std::string endpoint){
+PubSocket * PubSocket::create(Context * context, std::string endpoint, bool check_endpoint){
PubSocket *s = PubSocket::create();
- int r = s->connect(context, endpoint);
+ int r = s->connect(context, endpoint, check_endpoint);
if (r == 0) {
return s;
@@ -88,7 +68,7 @@ PubSocket * PubSocket::create(Context * context, std::string endpoint){
Poller * Poller::create(){
Poller * p;
- if (std::getenv("ZMQ") || MUST_USE_ZMQ){
+ if (messaging_use_zmq()){
p = new ZMQPoller();
} else {
p = new MSGQPoller();
diff --git a/cereal/messaging/messaging.hpp b/cereal/messaging/messaging.hpp
index 9ade8bf2b..6531de629 100644
--- a/cereal/messaging/messaging.hpp
+++ b/cereal/messaging/messaging.hpp
@@ -12,6 +12,8 @@
#define MSG_MULTIPLE_PUBLISHERS 100
+bool messaging_use_zmq();
+
class Context {
public:
virtual void * getRawContext() = 0;
@@ -32,24 +34,23 @@ public:
class SubSocket {
public:
- virtual int connect(Context *context, std::string endpoint, std::string address, bool conflate=false) = 0;
+ virtual int connect(Context *context, std::string endpoint, std::string address, bool conflate=false, bool check_endpoint=true) = 0;
virtual void setTimeout(int timeout) = 0;
virtual Message *receive(bool non_blocking=false) = 0;
virtual void * getRawSocket() = 0;
static SubSocket * create();
- static SubSocket * create(Context * context, std::string endpoint);
- static SubSocket * create(Context * context, std::string endpoint, std::string address);
- static SubSocket * create(Context * context, std::string endpoint, std::string address, bool conflate);
+ static SubSocket * create(Context * context, std::string endpoint, std::string address="127.0.0.1", bool conflate=false, bool check_endpoint=true);
virtual ~SubSocket(){};
};
class PubSocket {
public:
- virtual int connect(Context *context, std::string endpoint) = 0;
+ 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;
static PubSocket * create();
- static PubSocket * create(Context * context, std::string endpoint);
+ 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);
virtual ~PubSocket(){};
};
diff --git a/cereal/messaging/msgq.cc b/cereal/messaging/msgq.cc
index 30b0225cd..a51aef8e8 100644
--- a/cereal/messaging/msgq.cc
+++ b/cereal/messaging/msgq.cc
@@ -21,8 +21,6 @@
#include
-#include "services.h"
-
#include "msgq.hpp"
void sigusr2_handler(int signal) {
@@ -83,20 +81,9 @@ void msgq_wait_for_subscriber(msgq_queue_t *q){
return;
}
-bool service_exists(std::string path){
- for (const auto& it : services) {
- if (it.name == path) {
- return true;
- }
- }
- return false;
-}
int msgq_new_queue(msgq_queue_t * q, const char * path, size_t size){
assert(size < 0xFFFFFFFF); // Buffer must be smaller than 2^32 bytes
- if (!service_exists(std::string(path))){
- std::cout << "Warning, " << std::string(path) << " is not in service list." << std::endl;
- }
std::signal(SIGUSR2, sigusr2_handler);
const char * prefix = "/dev/shm/";
diff --git a/cereal/service_list.yaml b/cereal/service_list.yaml
deleted file mode 100644
index b140251cf..000000000
--- a/cereal/service_list.yaml
+++ /dev/null
@@ -1,180 +0,0 @@
-# TODO: these port numbers are hardcoded in c, fix this
-
-# LogRotate: 8001 is a PUSH PULL socket between loggerd and visiond
-
-# all ZMQ pub sub: port, should_log, frequency, (qlog_decimation)
-
-# frame syncing packet
-frame: [8002, true, 20., 1]
-# accel, gyro, and compass
-sensorEvents: [8003, true, 100., 100]
-# GPS data, also global timestamp
-gpsNMEA: [8004, true, 9.] # 9 msgs each sec
-# CPU+MEM+GPU+BAT temps
-thermal: [8005, true, 2., 1]
-# List(CanData), list of can messages
-can: [8006, true, 100.]
-controlsState: [8007, true, 100., 100]
-#liveEvent: [8008, true, 0.]
-model: [8009, true, 20., 5]
-features: [8010, true, 0.]
-health: [8011, true, 2., 1]
-radarState: [8012, true, 20., 5]
-#liveUI: [8014, true, 0.]
-encodeIdx: [8015, true, 20.]
-liveTracks: [8016, true, 20.]
-sendcan: [8017, true, 100.]
-logMessage: [8018, true, 0.]
-liveCalibration: [8019, true, 4., 4]
-androidLog: [8020, true, 0.]
-carState: [8021, true, 100., 10]
-# 8022 is reserved for sshd
-carControl: [8023, true, 100., 10]
-plan: [8024, true, 20., 2]
-liveLocation: [8025, true, 0., 1]
-gpsLocation: [8026, true, 1., 1]
-ethernetData: [8027, true, 0.]
-navUpdate: [8028, true, 0.]
-qcomGnss: [8029, true, 0.]
-lidarPts: [8030, true, 0.]
-procLog: [8031, true, 0.5]
-gpsLocationExternal: [8032, true, 10., 1]
-ubloxGnss: [8033, true, 10.]
-clocks: [8034, true, 1., 1]
-liveMpc: [8035, false, 20.]
-liveLongitudinalMpc: [8036, false, 20.]
-navStatus: [8038, true, 0.]
-gpsLocationTrimble: [8039, true, 0.]
-trimbleGnss: [8041, true, 0.]
-ubloxRaw: [8042, true, 20.]
-gpsPlannerPoints: [8043, true, 0.]
-gpsPlannerPlan: [8044, true, 0.]
-applanixRaw: [8046, true, 0.]
-orbLocation: [8047, true, 0.]
-trafficEvents: [8048, true, 0.]
-liveLocationTiming: [8049, true, 0.]
-orbslamCorrection: [8050, true, 0.]
-liveLocationCorrected: [8051, true, 0.]
-orbObservation: [8052, true, 0.]
-applanixLocation: [8053, true, 0.]
-liveLocationKalman: [8054, true, 20., 2]
-uiNavigationEvent: [8055, true, 0.]
-orbOdometry: [8057, true, 0.]
-orbFeatures: [8058, false, 0.]
-orbKeyFrame: [8059, true, 0.]
-uiLayoutState: [8060, true, 0.]
-frontEncodeIdx: [8061, true, 5.] # should be 20fps on tici
-orbFeaturesSummary: [8062, true, 0.]
-driverState: [8063, true, 5., 1]
-liveParameters: [8064, true, 20., 2]
-liveMapData: [8065, true, 0.]
-cameraOdometry: [8066, true, 20., 5]
-pathPlan: [8067, true, 20., 2]
-kalmanOdometry: [8068, true, 0.]
-thumbnail: [8069, true, 0.2, 1]
-carEvents: [8070, true, 1., 1]
-carParams: [8071, true, 0.02, 1]
-frontFrame: [8072, true, 10.]
-dMonitoringState: [8073, true, 5., 1]
-offroadLayout: [8074, false, 0.]
-wideEncodeIdx: [8075, true, 20.]
-wideFrame: [8076, true, 20.]
-modelV2: [8077, true, 20., 20]
-
-testModel: [8040, false, 0.]
-testLiveLocation: [8045, false, 0.]
-testJoystick: [8056, false, 0.]
-
-# 8080 is reserved for slave testing daemon
-# 8762 is reserved for logserver
-
-# manager -- base process to manage starting and stopping of all others
-# subscribes: thermal
-
-# **** processes that communicate with the outside world ****
-
-# thermald -- decides when to start and stop onroad
-# subscribes: health, location
-# publishes: thermal
-
-# boardd -- communicates with the car
-# subscribes: sendcan
-# publishes: can, health, ubloxRaw
-
-# sensord -- publishes IMU and Magnetometer
-# publishes: sensorEvents
-
-# gpsd -- publishes EON's gps
-# publishes: gpsNMEA
-
-# camerad -- publishes camera frames
-# publishes: frame, frontFrame, thumbnail
-# subscribes: driverState
-
-# dmonitoringmodeld -- runs face detection on camera frames
-# publishes: driverState
-
-# **** stateful data transformers ****
-
-# modeld -- runs & publishes the model
-# publishes: model, cameraOdometry
-# subscribes: liveCalibration, pathPlan
-
-# plannerd -- decides where to drive the car
-# subscribes: carState, model, radarState, controlsState, liveParameters
-# publishes: plan, pathPlan, liveMpc, liveLongitudinalMpc
-
-# controlsd -- drives the car by sending CAN messages to panda
-# subscribes: can, thermal, health, plan, pathPlan, dMonitoringState, liveCalibration, model
-# publishes: carState, carControl, sendcan, controlsState, carEvents, carParams
-
-# dmonitoringd -- processes driver monitoring data and publishes driver awareness
-# subscribes: driverState, liveCalibration, carState, model, gpsLocation
-# publishes: dMonitoringState
-
-# radard -- processes the radar and vision data
-# subscribes: can, controlsState, model, liveParameters
-# publishes: radarState, liveTracks
-
-# params_learner -- learns vehicle params by observing the vehicle dynamics
-# subscribes: controlsState, sensorEvents, cameraOdometry
-# publishes: liveParameters
-
-# calibrationd -- reads posenet and applies a temporal filter on the frame region to look at
-# subscribes: cameraOdometry
-# publishes: liveCalibration
-
-# ubloxd -- read raw ublox data and converts them in readable format
-# subscribes: ubloxRaw
-# publishes: ubloxGnss
-
-# **** LOGGING SERVICE ****
-
-# loggerd
-# subscribes: EVERYTHING
-
-# **** NON VITAL SERVICES ****
-
-# ui
-# subscribes: thermal, model, controlsState, uiLayout, liveCalibration, radarState, liveMpc, plusFrame, liveMapData
-
-# uploader
-# communicates through file system with loggerd
-
-# deleter
-# communicates through file system with loggerd and uploader
-
-# logmessaged -- central logging service, can log to cloud
-# publishes: logMessage
-
-# logcatd -- fetches logcat info from android
-# publishes: androidLog
-
-# proclogd -- fetches process information
-# publishes: procLog
-
-# tombstoned -- reports native crashes
-
-# athenad -- on request, open a sub socket and return the value
-
-# updated -- waits for network access and tries to update every hour
diff --git a/cereal/services.py b/cereal/services.py
index b22305945..daf6d6def 100755
--- a/cereal/services.py
+++ b/cereal/services.py
@@ -1,34 +1,84 @@
#!/usr/bin/env python3
import os
-import yaml
+from typing import Optional
+EON = os.path.isfile('/EON')
-class Service():
- def __init__(self, port, should_log, frequency, decimation=None):
+class Service:
+ def __init__(self, port: int, should_log: bool, frequency: float, decimation: Optional[int] = None):
self.port = port
self.should_log = should_log
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),
+ "gpsLocation": Service(8026, True, 1., 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),
-service_list_path = os.path.join(os.path.dirname(__file__), "service_list.yaml")
+ "testModel": Service(8040, False, 0.),
+ "testLiveLocation": Service(8045, False, 0.),
+ "testJoystick": Service(8056, False, 0.),
+}
-service_list = {}
-with open(service_list_path, "r") as f:
- for k, v in yaml.safe_load(f).items():
- decimation = None
- if len(v) == 4:
- decimation = v[3]
- service_list[k] = Service(v[0], v[1], v[2], decimation)
+def build_header():
+ h = ""
+ h += "/* THIS IS AN AUTOGENERATED FILE, PLEASE EDIT services.py */\n"
+ h += "#ifndef __SERVICES_H\n"
+ h += "#define __SERVICES_H\n"
+ h += "struct service { char name[0x100]; int port; bool should_log; int frequency; int decimation; };\n"
+ h += "static struct service services[] = {\n"
+ for k, v in service_list.items():
+ should_log = "true" if v.should_log else "false"
+ decimation = -1 if v.decimation is None else v.decimation
+ h += ' { .name = "%s", .port = %d, .should_log = %s, .frequency = %d, .decimation = %d },\n' % \
+ (k, v.port, should_log, v.frequency, decimation)
+ h += "};\n"
+ h += "#endif\n"
+ return h
+
if __name__ == "__main__":
- print("/* THIS IS AN AUTOGENERATED FILE, PLEASE EDIT service_list.yaml */")
- print("#ifndef __SERVICES_H")
- print("#define __SERVICES_H")
- print("struct service { char name[0x100]; int port; bool should_log; int frequency; int decimation; };")
- print("static struct service services[] = {")
- for k, v in service_list.items():
- print(' { .name = "%s", .port = %d, .should_log = %s, .frequency = %d, .decimation = %d },' % (k, v.port, "true" if v.should_log else "false", v.frequency, -1 if v.decimation is None else v.decimation))
- print("};")
- print("#endif")
+ print(build_header())
diff --git a/cereal/visionipc/.gitignore b/cereal/visionipc/.gitignore
new file mode 100644
index 000000000..fa5a2b9f3
--- /dev/null
+++ b/cereal/visionipc/.gitignore
@@ -0,0 +1,2 @@
+visionipc_pyx.cpp
+*.so
diff --git a/cereal/visionipc/__init__.py b/cereal/visionipc/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/selfdrive/common/ipc.c b/cereal/visionipc/ipc.cc
similarity index 85%
rename from selfdrive/common/ipc.c
rename to cereal/visionipc/ipc.cc
index a5993598d..29c4c9c37 100644
--- a/selfdrive/common/ipc.c
+++ b/cereal/visionipc/ipc.cc
@@ -1,6 +1,5 @@
#include
#include
-#include
#include
#include
#include
@@ -10,16 +9,19 @@
#include
#include
+#ifdef __APPLE__
+#define getsocket() socket(AF_UNIX, SOCK_STREAM, 0)
+#else
+#define getsocket() socket(AF_UNIX, SOCK_SEQPACKET, 0)
+#endif
+
#include "ipc.h"
int ipc_connect(const char* socket_path) {
int err;
-#ifdef __APPLE__
- int sock = socket(AF_UNIX, SOCK_STREAM, 0);
-#else
- int sock = socket(AF_UNIX, SOCK_SEQPACKET, 0);
-#endif
+ int sock = getsocket();
+
if (sock < 0) return -1;
struct sockaddr_un addr = {
.sun_family = AF_UNIX,
@@ -39,11 +41,8 @@ int ipc_bind(const char* socket_path) {
unlink(socket_path);
-#ifdef __APPLE__
- int sock = socket(AF_UNIX, SOCK_STREAM, 0);
-#else
- int sock = socket(AF_UNIX, SOCK_SEQPACKET, 0);
-#endif
+ int sock = getsocket();
+
struct sockaddr_un addr = {
.sun_family = AF_UNIX,
};
@@ -87,7 +86,6 @@ int ipc_sendrecv_with_fds(bool send, int fd, void *buf, size_t buf_size, int* fd
cmsg->cmsg_type = SCM_RIGHTS;
cmsg->cmsg_len = CMSG_LEN(sizeof(int) * num_fds);
memcpy(CMSG_DATA(cmsg), fds, sizeof(int) * num_fds);
- // printf("send clen %d -> %d\n", num_fds, cmsg->cmsg_len);
}
return sendmsg(fd, &msg, 0);
} else {
@@ -102,8 +100,6 @@ int ipc_sendrecv_with_fds(bool send, int fd, void *buf, size_t buf_size, int* fd
recv_fds = (cmsg->cmsg_len - CMSG_LEN(0));
assert(recv_fds > 0 && (recv_fds % sizeof(int)) == 0);
recv_fds /= sizeof(int);
- // printf("recv clen %d -> %d\n", cmsg->cmsg_len, recv_fds);
- // assert(cmsg->cmsg_len == CMSG_LEN(sizeof(int) * num_fds));
assert(fds && recv_fds <= num_fds);
memcpy(fds, CMSG_DATA(cmsg), sizeof(int) * recv_fds);
diff --git a/selfdrive/common/ipc.h b/cereal/visionipc/ipc.h
similarity index 61%
rename from selfdrive/common/ipc.h
rename to cereal/visionipc/ipc.h
index 7ebfd7164..14bb61a52 100644
--- a/selfdrive/common/ipc.h
+++ b/cereal/visionipc/ipc.h
@@ -1,19 +1,7 @@
-#ifndef IPC_H
-#define IPC_H
-
-#include
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+#pragma once
+#include
int ipc_connect(const char* socket_path);
int ipc_bind(const char* socket_path);
int ipc_sendrecv_with_fds(bool send, int fd, void *buf, size_t buf_size, int* fds, int num_fds,
int *out_num_fds);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif
\ No newline at end of file
diff --git a/cereal/visionipc/test_runner.cc b/cereal/visionipc/test_runner.cc
new file mode 100644
index 000000000..62bf7476a
--- /dev/null
+++ b/cereal/visionipc/test_runner.cc
@@ -0,0 +1,2 @@
+#define CATCH_CONFIG_MAIN
+#include "catch2/catch.hpp"
diff --git a/cereal/visionipc/visionbuf.cc b/cereal/visionipc/visionbuf.cc
new file mode 100644
index 000000000..64693b572
--- /dev/null
+++ b/cereal/visionipc/visionbuf.cc
@@ -0,0 +1,40 @@
+#include "visionbuf.h"
+
+#define ALIGN(x, align) (((x) + (align)-1) & ~((align)-1))
+
+#ifdef QCOM
+// from libadreno_utils.so
+extern "C" void compute_aligned_width_and_height(int width,
+ int height,
+ int bpp,
+ int tile_mode,
+ int raster_mode,
+ int padding_threshold,
+ int *aligned_w,
+ int *aligned_h);
+#endif
+
+void visionbuf_compute_aligned_width_and_height(int width, int height, int *aligned_w, int *aligned_h) {
+#if defined(QCOM) && !defined(QCOM_REPLAY)
+ compute_aligned_width_and_height(ALIGN(width, 32), ALIGN(height, 32), 3, 0, 0, 512, aligned_w, aligned_h);
+#else
+ *aligned_w = width; *aligned_h = height;
+#endif
+}
+
+void VisionBuf::init_rgb(size_t width, size_t height, size_t stride) {
+ this->rgb = true;
+ this->width = width;
+ this->height = height;
+ this->stride = stride;
+}
+
+void VisionBuf::init_yuv(size_t width, size_t height){
+ this->rgb = false;
+ this->width = width;
+ this->height = height;
+
+ this->y = (uint8_t *)this->addr;
+ this->u = this->y + (width * height);
+ this->v = this->u + (width / 2 * height / 2);
+}
diff --git a/cereal/visionipc/visionbuf.h b/cereal/visionipc/visionbuf.h
new file mode 100644
index 000000000..f6d84f4c1
--- /dev/null
+++ b/cereal/visionipc/visionbuf.h
@@ -0,0 +1,63 @@
+#pragma once
+#include "visionipc.h"
+
+#define CL_USE_DEPRECATED_OPENCL_1_2_APIS
+#ifdef __APPLE__
+#include
+#else
+#include
+#endif
+
+#define VISIONBUF_SYNC_FROM_DEVICE 0
+#define VISIONBUF_SYNC_TO_DEVICE 1
+
+enum VisionStreamType {
+ VISION_STREAM_RGB_BACK,
+ VISION_STREAM_RGB_FRONT,
+ VISION_STREAM_RGB_WIDE,
+ VISION_STREAM_YUV_BACK,
+ VISION_STREAM_YUV_FRONT,
+ VISION_STREAM_YUV_WIDE,
+ VISION_STREAM_MAX,
+};
+
+class VisionBuf {
+ public:
+ size_t len = 0;
+ size_t mmap_len = 0;
+ void * addr = nullptr;
+ int fd = 0;
+
+ bool rgb = false;
+ size_t width = 0;
+ size_t height = 0;
+ size_t stride = 0;
+
+ // YUV
+ uint8_t * y = nullptr;
+ uint8_t * u = nullptr;
+ uint8_t * v = nullptr;
+
+ // Visionipc
+ uint64_t server_id = 0;
+ size_t idx = 0;
+ VisionStreamType type;
+
+ // OpenCL
+ cl_mem buf_cl = nullptr;
+ cl_command_queue copy_q = nullptr;
+
+ // ion
+ int handle = 0;
+ bool owner = false;
+
+ void allocate(size_t len);
+ void import();
+ void init_cl(cl_device_id device_id, cl_context ctx);
+ void init_rgb(size_t width, size_t height, size_t stride);
+ void init_yuv(size_t width, size_t height);
+ void sync(int dir);
+ void free();
+};
+
+void visionbuf_compute_aligned_width_and_height(int width, int height, int *aligned_w, int *aligned_h);
diff --git a/cereal/visionipc/visionbuf_cl.cc b/cereal/visionipc/visionbuf_cl.cc
new file mode 100644
index 000000000..6fb2884b5
--- /dev/null
+++ b/cereal/visionipc/visionbuf_cl.cc
@@ -0,0 +1,86 @@
+#include "visionbuf.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+std::atomic offset = 0;
+
+static void *malloc_with_fd(size_t len, int *fd) {
+ char full_path[0x100];
+
+#ifdef __APPLE__
+ snprintf(full_path, sizeof(full_path)-1, "/tmp/visionbuf_%d_%d", getpid(), offset++);
+#else
+ snprintf(full_path, sizeof(full_path)-1, "/dev/shm/visionbuf_%d_%d", getpid(), offset++);
+#endif
+
+ *fd = open(full_path, O_RDWR | O_CREAT, 0777);
+ assert(*fd >= 0);
+
+ unlink(full_path);
+
+ ftruncate(*fd, len);
+ void *addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, *fd, 0);
+ assert(addr != MAP_FAILED);
+
+ return addr;
+}
+
+void VisionBuf::allocate(size_t len) {
+ int fd;
+ void *addr = malloc_with_fd(len, &fd);
+
+ this->len = len;
+ this->mmap_len = len;
+ this->addr = addr;
+ this->fd = fd;
+}
+
+void VisionBuf::init_cl(cl_device_id device_id, cl_context ctx){
+ int err;
+
+ this->copy_q = clCreateCommandQueue(ctx, device_id, 0, &err);
+ assert(err == 0);
+
+ this->buf_cl = clCreateBuffer(ctx, CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, this->len, this->addr, &err);
+ assert(err == 0);
+}
+
+
+void VisionBuf::import(){
+ assert(this->fd >= 0);
+ this->addr = mmap(NULL, this->mmap_len, PROT_READ | PROT_WRITE, MAP_SHARED, this->fd, 0);
+ assert(this->addr != MAP_FAILED);
+}
+
+
+void VisionBuf::sync(int dir) {
+ int err = 0;
+ if (!this->buf_cl) return;
+
+ if (dir == VISIONBUF_SYNC_FROM_DEVICE) {
+ err = clEnqueueReadBuffer(this->copy_q, this->buf_cl, CL_FALSE, 0, this->len, this->addr, 0, NULL, NULL);
+ } else {
+ err = clEnqueueWriteBuffer(this->copy_q, this->buf_cl, CL_FALSE, 0, this->len, this->addr, 0, NULL, NULL);
+ }
+ assert(err == 0);
+ clFinish(this->copy_q);
+}
+
+void VisionBuf::free() {
+ if (this->buf_cl){
+ int err = clReleaseMemObject(this->buf_cl);
+ assert(err == 0);
+
+ clReleaseCommandQueue(this->copy_q);
+ }
+
+ munmap(this->addr, this->len);
+ close(this->fd);
+}
diff --git a/selfdrive/common/visionbuf_ion.c b/cereal/visionipc/visionbuf_ion.cc
similarity index 60%
rename from selfdrive/common/visionbuf_ion.c
rename to cereal/visionipc/visionbuf_ion.cc
index 5c26bea6a..31448daed 100644
--- a/selfdrive/common/visionbuf_ion.c
+++ b/cereal/visionipc/visionbuf_ion.cc
@@ -10,7 +10,7 @@
#include
#include
#include
-#include "common/clutil.h"
+
#include
#include "visionbuf.h"
@@ -36,7 +36,7 @@ static void ion_init() {
}
}
-VisionBuf visionbuf_allocate(size_t len) {
+void VisionBuf::allocate(size_t len) {
int err;
ion_init();
@@ -62,46 +62,58 @@ VisionBuf visionbuf_allocate(size_t len) {
memset(addr, 0, ion_alloc.len);
- return (VisionBuf){
- .len = len,
- .mmap_len = ion_alloc.len,
- .addr = addr,
- .handle = ion_alloc.handle,
- .fd = ion_fd_data.fd,
- };
+ this->owner = true;
+ this->len = len;
+ this->mmap_len = ion_alloc.len;
+ this->addr = addr;
+ this->handle = ion_alloc.handle;
+ this->fd = ion_fd_data.fd;
}
-VisionBuf visionbuf_allocate_cl(size_t len, cl_device_id device_id, cl_context ctx) {
- VisionBuf buf = visionbuf_allocate(len);
+void VisionBuf::import(){
+ int err;
+ assert(this->fd >= 0);
- assert(((uintptr_t)buf.addr % DEVICE_PAGE_SIZE_CL) == 0);
+ ion_init();
+
+ // Get handle
+ struct ion_fd_data fd_data = {0};
+ fd_data.fd = this->fd;
+ err = ioctl(ion_fd, ION_IOC_IMPORT, &fd_data);
+ assert(err == 0);
+
+ this->owner = false;
+ this->handle = fd_data.handle;
+ this->addr = mmap(NULL, this->mmap_len, PROT_READ | PROT_WRITE, MAP_SHARED, this->fd, 0);
+ assert(this->addr != MAP_FAILED);
+}
+
+void VisionBuf::init_cl(cl_device_id device_id, cl_context ctx) {
+ int err;
+
+ assert(((uintptr_t)this->addr % DEVICE_PAGE_SIZE_CL) == 0);
cl_mem_ion_host_ptr ion_cl = {0};
ion_cl.ext_host_ptr.allocation_type = CL_MEM_ION_HOST_PTR_QCOM;
ion_cl.ext_host_ptr.host_cache_policy = CL_MEM_HOST_UNCACHED_QCOM;
- ion_cl.ion_filedesc = buf.fd;
- ion_cl.ion_hostptr = buf.addr;
+ ion_cl.ion_filedesc = this->fd;
+ ion_cl.ion_hostptr = this->addr;
- buf.buf_cl = CL_CHECK_ERR(clCreateBuffer(ctx,
+ this->buf_cl = clCreateBuffer(ctx,
CL_MEM_USE_HOST_PTR | CL_MEM_EXT_HOST_PTR_QCOM,
- buf.len, &ion_cl, &err));
- return buf;
+ this->len, &ion_cl, &err);
+ assert(err == 0);
}
-void visionbuf_sync(const VisionBuf* buf, int dir) {
+void VisionBuf::sync(int dir) {
int err;
- struct ion_fd_data fd_data = {0};
- fd_data.fd = buf->fd;
- err = ioctl(ion_fd, ION_IOC_IMPORT, &fd_data);
- assert(err == 0);
-
struct ion_flush_data flush_data = {0};
- flush_data.handle = fd_data.handle;
- flush_data.vaddr = buf->addr;
+ flush_data.handle = this->handle;
+ flush_data.vaddr = this->addr;
flush_data.offset = 0;
- flush_data.length = buf->len;
+ flush_data.length = this->len;
// ION_IOC_INV_CACHES ~= DMA_FROM_DEVICE
// ION_IOC_CLEAN_CACHES ~= DMA_TO_DEVICE
@@ -109,36 +121,28 @@ void visionbuf_sync(const VisionBuf* buf, int dir) {
struct ion_custom_data custom_data = {0};
- switch (dir) {
- case VISIONBUF_SYNC_FROM_DEVICE:
- custom_data.cmd = ION_IOC_INV_CACHES;
- break;
- case VISIONBUF_SYNC_TO_DEVICE:
- custom_data.cmd = ION_IOC_CLEAN_CACHES;
- break;
- default:
- assert(0);
- }
+ assert(dir == VISIONBUF_SYNC_FROM_DEVICE || dir == VISIONBUF_SYNC_TO_DEVICE);
+ custom_data.cmd = (dir == VISIONBUF_SYNC_FROM_DEVICE) ?
+ ION_IOC_INV_CACHES : ION_IOC_CLEAN_CACHES;
custom_data.arg = (unsigned long)&flush_data;
err = ioctl(ion_fd, ION_IOC_CUSTOM, &custom_data);
assert(err == 0);
-
- struct ion_handle_data handle_data = {0};
- handle_data.handle = fd_data.handle;
- err = ioctl(ion_fd, ION_IOC_FREE, &handle_data);
- assert(err == 0);
}
-void visionbuf_free(const VisionBuf* buf) {
- if (buf->buf_cl) {
- CL_CHECK(clReleaseMemObject(buf->buf_cl));
+void VisionBuf::free() {
+ if (this->buf_cl){
+ int err = clReleaseMemObject(this->buf_cl);
+ assert(err == 0);
+ }
+
+ munmap(this->addr, this->mmap_len);
+ close(this->fd);
+
+ // Free the ION buffer if we also shared it
+ if (this->owner){
+ struct ion_handle_data handle_data = {.handle = this->handle};
+ int ret = ioctl(ion_fd, ION_IOC_FREE, &handle_data);
+ assert(ret == 0);
}
- munmap(buf->addr, buf->mmap_len);
- close(buf->fd);
- struct ion_handle_data handle_data = {
- .handle = buf->handle,
- };
- int ret = ioctl(ion_fd, ION_IOC_FREE, &handle_data);
- assert(ret == 0);
}
diff --git a/cereal/visionipc/visionipc.h b/cereal/visionipc/visionipc.h
new file mode 100644
index 000000000..8ecb7da16
--- /dev/null
+++ b/cereal/visionipc/visionipc.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#include
+#include
+
+constexpr int VISIONIPC_MAX_FDS = 64;
+
+struct VisionIpcBufExtra {
+ uint32_t frame_id;
+ uint64_t timestamp_sof;
+ uint64_t timestamp_eof;
+};
+
+struct VisionIpcPacket {
+ uint64_t server_id;
+ size_t idx;
+ struct VisionIpcBufExtra extra;
+};
diff --git a/cereal/visionipc/visionipc.pxd b/cereal/visionipc/visionipc.pxd
new file mode 100644
index 000000000..00a17762a
--- /dev/null
+++ b/cereal/visionipc/visionipc.pxd
@@ -0,0 +1,29 @@
+# distutils: language = c++
+#cython: language_level=3
+
+from libcpp.string cimport string
+from libcpp.vector cimport vector
+from libc.stdint cimport uint32_t, uint64_t
+from libcpp cimport bool
+
+cdef extern from "visionbuf.h":
+ cdef enum VisionStreamType:
+ pass
+
+ cdef cppclass VisionBuf:
+ void * addr
+ size_t len
+
+cdef extern from "visionipc.h":
+ struct VisionIpcBufExtra:
+ uint32_t frame_id
+ uint64_t timestamp_sof
+ uint64_t timestamp_eof
+
+cdef extern from "visionipc_server.h":
+ cdef cppclass VisionIpcServer:
+ VisionIpcServer(string, void*, void*)
+ void create_buffers(VisionStreamType, size_t, bool, size_t, size_t)
+ VisionBuf * get_buffer(VisionStreamType)
+ void send(VisionBuf *, VisionIpcBufExtra *, bool)
+ void start_listener()
diff --git a/cereal/visionipc/visionipc_client.cc b/cereal/visionipc/visionipc_client.cc
new file mode 100644
index 000000000..d46cc0e4a
--- /dev/null
+++ b/cereal/visionipc/visionipc_client.cc
@@ -0,0 +1,119 @@
+#include
+#include
+#include
+#include
+
+#include "ipc.h"
+#include "visionipc_client.h"
+#include "visionipc_server.h"
+
+VisionIpcClient::VisionIpcClient(std::string name, VisionStreamType type, bool conflate, cl_device_id device_id, cl_context ctx) : name(name), type(type), device_id(device_id), ctx(ctx) {
+ msg_ctx = Context::create();
+ sock = SubSocket::create(msg_ctx, get_endpoint_name(name, type), "127.0.0.1", conflate, false);
+
+ poller = Poller::create();
+ poller->registerSocket(sock);
+}
+
+// Connect is not thread safe. Do not use the buffers while calling connect
+bool VisionIpcClient::connect(bool blocking){
+ connected = false;
+
+ // Cleanup old buffers on reconnect
+ for (size_t i = 0; i < num_buffers; i++){
+ buffers[i].free();
+ }
+ num_buffers = 0;
+
+ // Connect to server socket and ask for all FDs of type
+ std::string path = "/tmp/visionipc_" + name;
+
+ int socket_fd = -1;
+ while (socket_fd < 0) {
+ socket_fd = ipc_connect(path.c_str());
+
+ if (socket_fd < 0) {
+ if (blocking){
+ std::cout << "VisionIpcClient connecting" << std::endl;
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+ } else {
+ return false;
+ }
+ }
+ }
+
+ // Send stream type to server to request FDs
+ int r = ipc_sendrecv_with_fds(true, socket_fd, &type, sizeof(type), nullptr, 0, nullptr);
+ assert(r == sizeof(type));
+
+ // Get FDs
+ int fds[VISIONIPC_MAX_FDS];
+ VisionBuf bufs[VISIONIPC_MAX_FDS];
+ r = ipc_sendrecv_with_fds(false, socket_fd, &bufs, sizeof(bufs), fds, VISIONIPC_MAX_FDS, &num_buffers);
+
+ assert(num_buffers > 0);
+ assert(r == sizeof(VisionBuf) * num_buffers);
+
+ // Import buffers
+ for (size_t i = 0; i < num_buffers; i++){
+ buffers[i] = bufs[i];
+ buffers[i].fd = fds[i];
+ buffers[i].import();
+ if (buffers[i].rgb) {
+ buffers[i].init_rgb(buffers[i].width, buffers[i].height, buffers[i].stride);
+ } else {
+ buffers[i].init_yuv(buffers[i].width, buffers[i].height);
+ }
+
+ if (device_id) buffers[i].init_cl(device_id, ctx);
+ }
+
+ connected = true;
+ return true;
+}
+
+VisionBuf * VisionIpcClient::recv(VisionIpcBufExtra * extra, const int timeout_ms){
+ auto p = poller->poll(timeout_ms);
+
+ if (!p.size()){
+ return nullptr;
+ }
+
+ Message * r = sock->receive(true);
+ if (r == nullptr){
+ return nullptr;
+ }
+
+ // Get buffer
+ assert(r->getSize() == sizeof(VisionIpcPacket));
+ VisionIpcPacket *packet = (VisionIpcPacket*)r->getData();
+
+ assert(packet->idx < num_buffers);
+ VisionBuf * buf = &buffers[packet->idx];
+
+ if (buf->server_id != packet->server_id){
+ connected = false;
+ delete r;
+ return nullptr;
+ }
+
+ if (extra) {
+ *extra = packet->extra;
+ }
+
+ buf->sync(VISIONBUF_SYNC_TO_DEVICE);
+ delete r;
+ return buf;
+}
+
+
+
+VisionIpcClient::~VisionIpcClient(){
+ for (size_t i = 0; i < num_buffers; i++){
+ buffers[i].free();
+ }
+
+ delete sock;
+ delete poller;
+ delete msg_ctx;
+}
diff --git a/cereal/visionipc/visionipc_client.h b/cereal/visionipc/visionipc_client.h
new file mode 100644
index 000000000..469976239
--- /dev/null
+++ b/cereal/visionipc/visionipc_client.h
@@ -0,0 +1,32 @@
+#pragma once
+#include
+#include
+#include
+
+#include "messaging.hpp"
+#include "visionipc.h"
+#include "visionbuf.h"
+
+class VisionIpcClient {
+private:
+ std::string name;
+ Context * msg_ctx;
+ SubSocket * sock;
+ Poller * poller;
+
+ VisionStreamType type;
+
+ cl_device_id device_id = nullptr;
+ cl_context ctx = nullptr;
+
+ void init_msgq(bool conflate);
+
+public:
+ bool connected = false;
+ int num_buffers = 0;
+ VisionBuf buffers[VISIONIPC_MAX_FDS];
+ VisionIpcClient(std::string name, VisionStreamType type, bool conflate, cl_device_id device_id=nullptr, cl_context ctx=nullptr);
+ ~VisionIpcClient();
+ VisionBuf * recv(VisionIpcBufExtra * extra=nullptr, const int timeout_ms=100);
+ bool connect(bool blocking=true);
+};
diff --git a/cereal/visionipc/visionipc_pyx.pyx b/cereal/visionipc/visionipc_pyx.pyx
new file mode 100644
index 000000000..fb8eed035
--- /dev/null
+++ b/cereal/visionipc/visionipc_pyx.pyx
@@ -0,0 +1,49 @@
+# distutils: language = c++
+# cython: c_string_encoding=ascii, language_level=3
+
+import sys
+from libcpp.string cimport string
+from libcpp cimport bool
+from libc.string cimport memcpy
+from libc.stdint cimport uint32_t, uint64_t
+
+from .visionipc cimport VisionIpcServer as cppVisionIpcServer
+from .visionipc cimport VisionBuf as cppVisionBuf
+from .visionipc cimport VisionIpcBufExtra
+
+cpdef enum VisionStreamType:
+ VISION_STREAM_RGB_BACK
+ VISION_STREAM_RGB_FRONT
+ VISION_STREAM_RGB_WIDE
+ VISION_STREAM_YUV_BACK
+ VISION_STREAM_YUV_FRONT
+ VISION_STREAM_YUV_WIDE
+
+cdef class VisionIpcServer:
+ cdef cppVisionIpcServer * server
+
+ def __init__(self, string name):
+ self.server = new cppVisionIpcServer(name, NULL, NULL)
+
+ def create_buffers(self, VisionStreamType tp, size_t num_buffers, bool rgb, size_t width, size_t height):
+ self.server.create_buffers(tp, num_buffers, rgb, width, height)
+
+ def send(self, VisionStreamType tp, bytes data, uint32_t frame_id=0, uint64_t timestamp_sof=0, uint64_t timestamp_eof=0):
+ cdef cppVisionBuf * buf = self.server.get_buffer(tp)
+
+ # Populate buffer
+ assert buf.len == len(data)
+ memcpy(buf.addr, data, len(data))
+
+ cdef VisionIpcBufExtra extra
+ extra.frame_id = frame_id
+ extra.timestamp_sof = timestamp_sof
+ extra.timestamp_eof = timestamp_eof
+
+ self.server.send(buf, &extra, False)
+
+ def start_listener(self):
+ self.server.start_listener()
+
+ def __dealloc__(self):
+ del self.server
diff --git a/cereal/visionipc/visionipc_server.cc b/cereal/visionipc/visionipc_server.cc
new file mode 100644
index 000000000..7c64cd839
--- /dev/null
+++ b/cereal/visionipc/visionipc_server.cc
@@ -0,0 +1,179 @@
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include "messaging.hpp"
+#include "ipc.h"
+#include "visionipc_server.h"
+
+std::string get_endpoint_name(std::string name, VisionStreamType type){
+ if (messaging_use_zmq()){
+ assert(name == "camerad");
+ return std::to_string(9000 + static_cast(type));
+ } else {
+ return "visionipc_" + name + "_" + std::to_string(type);
+ }
+}
+
+VisionIpcServer::VisionIpcServer(std::string name, cl_device_id device_id, cl_context ctx) : name(name), device_id(device_id), ctx(ctx) {
+ msg_ctx = Context::create();
+
+ std::random_device rd("/dev/urandom");
+ std::uniform_int_distribution distribution(0,std::numeric_limits::max());
+ server_id = distribution(rd);
+}
+
+void VisionIpcServer::create_buffers(VisionStreamType type, size_t num_buffers, bool rgb, size_t width, size_t height){
+ // TODO: assert that this type is not created yet
+ assert(num_buffers < VISIONIPC_MAX_FDS);
+ int aligned_w = 0, aligned_h = 0;
+
+ size_t size = 0;
+ size_t stride = 0; // Only used for RGB
+
+ if (rgb) {
+ visionbuf_compute_aligned_width_and_height(width, height, &aligned_w, &aligned_h);
+ size = (size_t)aligned_w * (size_t)aligned_h * 3;
+ stride = aligned_w * 3;
+ } else {
+ size = width * height * 3 / 2;
+ }
+
+
+ // Create map + alloc requested buffers
+ for (size_t i = 0; i < num_buffers; i++){
+ VisionBuf* buf = new VisionBuf();
+ buf->allocate(size);
+ buf->idx = i;
+ buf->type = type;
+
+ if (device_id) buf->init_cl(device_id, ctx);
+
+ rgb ? buf->init_rgb(width, height, stride) : buf->init_yuv(width, height);
+
+ buffers[type].push_back(buf);
+ }
+
+ cur_idx[type] = 0;
+
+ // Create msgq publisher for each of the `name` + type combos
+ // TODO: compute port number directly if using zmq
+ sockets[type] = PubSocket::create(msg_ctx, get_endpoint_name(name, type), false);
+}
+
+
+void VisionIpcServer::start_listener(){
+ listener_thread = std::thread(&VisionIpcServer::listener, this);
+}
+
+
+void VisionIpcServer::listener(){
+ std::cout << "Starting listener for: " << name << std::endl;
+
+ std::string path = "/tmp/visionipc_" + name;
+ int sock = ipc_bind(path.c_str());
+ assert(sock >= 0);
+
+ while (!should_exit){
+ // Wait for incoming connection
+ struct pollfd polls[1] = {{0}};
+ polls[0].fd = sock;
+ polls[0].events = POLLIN;
+
+ int ret = poll(polls, 1, 100);
+ if (ret < 0) {
+ if (errno == EINTR || errno == EAGAIN) continue;
+ std::cout << "poll failed, stopping listener" << std::endl;
+ break;
+ }
+
+ if (should_exit) break;
+ if (!polls[0].revents) {
+ continue;
+ }
+
+ // Handle incoming request
+ int fd = accept(sock, NULL, NULL);
+ assert(fd >= 0);
+
+ VisionStreamType type = VisionStreamType::VISION_STREAM_MAX;
+ int r = ipc_sendrecv_with_fds(false, fd, &type, sizeof(type), nullptr, 0, nullptr);
+ assert(r == sizeof(type));
+ if (buffers.count(type) <= 0) {
+ std::cout << "got request for invalid buffer type: " << type << std::endl;
+ close(fd);
+ continue;
+ }
+
+ int fds[VISIONIPC_MAX_FDS];
+ int num_fds = buffers[type].size();
+ VisionBuf bufs[VISIONIPC_MAX_FDS];
+
+ for (int i = 0; i < num_fds; i++){
+ fds[i] = buffers[type][i]->fd;
+ bufs[i] = *buffers[type][i];
+
+ // Remove some private openCL/ion metadata
+ bufs[i].buf_cl = 0;
+ bufs[i].copy_q = 0;
+ bufs[i].handle = 0;
+ bufs[i].owner = false;
+
+ bufs[i].server_id = server_id;
+ }
+
+ r = ipc_sendrecv_with_fds(true, fd, &bufs, sizeof(VisionBuf) * num_fds, fds, num_fds, nullptr);
+
+ close(fd);
+ }
+
+ std::cout << "Stopping listener for: " << name << std::endl;
+ close(sock);
+}
+
+
+
+VisionBuf * VisionIpcServer::get_buffer(VisionStreamType type){
+ // Do we want to keep track if the buffer has been sent out yet and warn user?
+ assert(buffers.count(type));
+ auto b = buffers[type];
+ return b[cur_idx[type]++ % b.size()];
+}
+
+void VisionIpcServer::send(VisionBuf * buf, VisionIpcBufExtra * extra, bool sync){
+ if (sync) buf->sync(VISIONBUF_SYNC_FROM_DEVICE);
+ assert(buffers.count(buf->type));
+ assert(buf->idx < buffers[buf->type].size());
+
+ // Send over correct msgq socket
+ VisionIpcPacket packet = {0};
+ packet.server_id = server_id;
+ packet.idx = buf->idx;
+ packet.extra = *extra;
+
+ sockets[buf->type]->send((char*)&packet, sizeof(packet));
+}
+
+VisionIpcServer::~VisionIpcServer(){
+ should_exit = true;
+ listener_thread.join();
+
+ // VisionBuf cleanup
+ for( auto const& [type, buf] : buffers ) {
+ for (VisionBuf* b : buf){
+ b->free();
+ delete b;
+ }
+ }
+
+ // Messaging cleanup
+ for( auto const& [type, sock] : sockets ) {
+ delete sock;
+ }
+ delete msg_ctx;
+}
diff --git a/cereal/visionipc/visionipc_server.h b/cereal/visionipc/visionipc_server.h
new file mode 100644
index 000000000..4472acf61
--- /dev/null
+++ b/cereal/visionipc/visionipc_server.h
@@ -0,0 +1,42 @@
+#pragma once
+#include
+#include
+#include
+#include
+#include