openpilot v0.7.10 release

Vehicle Researcher 2020-10-21 06:33:00 -07:00
parent db336329c5
commit 26bccbdcc8
184 changed files with 4675 additions and 3343 deletions

6
Jenkinsfile vendored
View File

@ -34,6 +34,9 @@ pipeline {
COMMA_JWT = credentials('athena-test-jwt')
TEST_DIR = "/data/openpilot"
}
options {
timeout(time: 1, unit: 'HOURS')
}
stages {
@ -58,7 +61,7 @@ pipeline {
when {
not {
anyOf {
branch 'master-ci'; branch 'devel'; branch 'devel-staging'; branch 'release2'; branch 'release2-staging'; branch 'dashcam'; branch 'dashcam-staging'
branch 'master-ci'; branch 'devel'; branch 'devel-staging'; branch 'release2'; branch 'release2-staging'; branch 'dashcam'; branch 'dashcam-staging'; branch 'testing-closet*'
}
}
}
@ -133,6 +136,7 @@ pipeline {
["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 updater", "python installer/updater/test_updater.py"],
])
}

View File

@ -66,6 +66,7 @@ Supported Cars
| ----------| ------------------------------| ------------------| -----------------| -------------------| ------------------|
| Acura | ILX 2016-18 | AcuraWatch Plus | openpilot | 25mph<sup>1</sup> | 25mph |
| Acura | RDX 2016-18 | AcuraWatch Plus | openpilot | 25mph<sup>1</sup> | 12mph |
| Acura | RDX 2020 | AcuraWatch | Stock | 0mph | 3mph |
| Honda | Accord 2018-20 | All | Stock | 0mph | 3mph |
| Honda | Accord Hybrid 2018-20 | All | Stock | 0mph | 3mph |
| Honda | Civic Hatchback 2017-19 | Honda Sensing | Stock | 0mph | 12mph |
@ -109,7 +110,7 @@ Supported Cars
| Toyota | Prius 2016-20 | TSS-P | Stock<sup>3</sup>| 0mph | 0mph |
| Toyota | Prius Prime 2017-20 | All | Stock<sup>3</sup>| 0mph | 0mph |
| Toyota | Rav4 2016-18 | TSS-P | Stock<sup>3</sup>| 20mph<sup>1</sup> | 0mph |
| Toyota | Rav4 2019-20 | All | openpilot | 0mph | 0mph |
| Toyota | Rav4 2019-21 | All | openpilot | 0mph | 0mph |
| Toyota | Rav4 Hybrid 2016-18 | TSS-P | Stock<sup>3</sup>| 0mph | 0mph |
| Toyota | Rav4 Hybrid 2019-20 | All | openpilot | 0mph | 0mph |
| Toyota | Sienna 2018-20 | All | Stock<sup>3</sup>| 0mph | 0mph |
@ -143,7 +144,7 @@ Community Maintained Cars and Features
| 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 | All | Stock | 0mph | 0mph |
| Hyundai | Sonata 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 |
@ -152,8 +153,8 @@ Community Maintained Cars and Features
| 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 | Leaf 2018-19 | ProPILOT | Stock | 0mph | 0mph |
| Nissan | Rogue 2019 | 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 |
| Subaru | Ascent 2019 | EyeSight | Stock | 0mph | 0mph |
| Subaru | Crosstrek 2018-19 | EyeSight | Stock | 0mph | 0mph |
@ -268,7 +269,7 @@ Safety and Testing
Testing on PC
------
For simplified development and experimentation, openpilot runs in the CARLA driving simulator, which allows you to develop openpilot without a car.
For simplified development and experimentation, openpilot can be run in the CARLA driving simulator, which allows you to develop openpilot without a car. The whole setup should only take a few minutes.
Steps:
1) Start the CARLA server on first terminal
@ -309,7 +310,7 @@ Directory Structure
├── phonelibs # Libraries used on NEOS devices
├── pyextra # Libraries used on NEOS devices
└── selfdrive # Code needed to drive the car
├── assets # Fonts, images, and sounds for UI
├── assets # Fonts, images and sounds for UI
├── athena # Allows communication with the app
├── boardd # Daemon to talk to the board
├── camerad # Driver to capture images from the camera sensors

View File

@ -1,3 +1,12 @@
Version 0.7.10 (2020-10-26)
========================
* NEOS update: update to Python 3.8.2 and lower CPU frequency
* Improved thermals due to reduced CPU frequency
* Update SNPE to 1.41.0
* Reduced offroad power consumption
* Various system stability improvements
* Acura RDX 2020 support thanks to csouers!
Version 0.7.9 (2020-10-09)
========================
* Improved car battery power management
@ -29,24 +38,24 @@ Version 0.7.7 (2020-07-20)
Version 0.7.6.1 (2020-06-16)
========================
* Hotfix: update kernel on some comma twos (orders #8570-#8680)
* Hotfix: update kernel on some comma twos (orders #8570-#8680)
Version 0.7.6 (2020-06-05)
========================
* White panda is deprecated, upgrade to comma two or black panda
* 2017 Nissan X-Trail, 2018-19 Leaf and 2019 Rogue support thanks to avolmensky!
* 2017 Mazda CX-5 support in dashcam mode thanks to Jafaral!
* Huge CPU savings in modeld by using thneed!
* Lots of code cleanup and refactors
* White panda is deprecated, upgrade to comma two or black panda
* 2017 Nissan X-Trail, 2018-19 Leaf and 2019 Rogue support thanks to avolmensky!
* 2017 Mazda CX-5 support in dashcam mode thanks to Jafaral!
* Huge CPU savings in modeld by using thneed!
* Lots of code cleanup and refactors
Version 0.7.5 (2020-05-13)
========================
* Right-Hand Drive support for both driving and driver monitoring!
* New driving model: improved at sharp turns and lead speed estimation
* New driver monitoring model: overall improvement on comma two
* Driver camera preview in settings to improve mounting position
* Added support for many Hyundai, Kia, Genesis models thanks to xx979xx!
* Improved lateral tuning for 2020 Toyota Rav 4 (hybrid)
* Right-Hand Drive support for both driving and driver monitoring!
* New driving model: improved at sharp turns and lead speed estimation
* New driver monitoring model: overall improvement on comma two
* Driver camera preview in settings to improve mounting position
* Added support for many Hyundai, Kia, Genesis models thanks to xx979xx!
* Improved lateral tuning for 2020 Toyota Rav 4 (hybrid)
Version 0.7.4 (2020-03-20)
========================
@ -482,96 +491,96 @@ Version 0.3.4 (2017-07-28)
Version 0.3.3 (2017-06-28)
===========================
* Improved model trained on more data
* Alpha CR-V support thanks to energee and johnnwvs!
* Using the opendbc project for DBC files
* Minor performance improvements
* UI update thanks to pjlao307
* Power off button
* 6% more torque on the Civic
* Improved model trained on more data
* Alpha CR-V support thanks to energee and johnnwvs!
* Using the opendbc project for DBC files
* Minor performance improvements
* UI update thanks to pjlao307
* Power off button
* 6% more torque on the Civic
Version 0.3.2 (2017-05-22)
===========================
* Minor stability bugfixes
* Added metrics and rear view mirror disable to settings
* Update model with more crowdsourced data
* Minor stability bugfixes
* Added metrics and rear view mirror disable to settings
* Update model with more crowdsourced data
Version 0.3.1 (2017-05-17)
===========================
* visiond stability bugfix
* Add logging for angle and flashing
* visiond stability bugfix
* Add logging for angle and flashing
Version 0.3.0 (2017-05-12)
===========================
* Add CarParams struct to improve the abstraction layer
* Refactor visiond IPC to support multiple clients
* Add raw GPS and beginning support for navigation
* Improve model in visiond using crowdsourced data
* Add improved system logging to diagnose instability
* Rewrite baseui in React Native
* Moved calibration to the cloud
* Add CarParams struct to improve the abstraction layer
* Refactor visiond IPC to support multiple clients
* Add raw GPS and beginning support for navigation
* Improve model in visiond using crowdsourced data
* Add improved system logging to diagnose instability
* Rewrite baseui in React Native
* Moved calibration to the cloud
Version 0.2.9 (2017-03-01)
===========================
* Retain compatibility with NEOS v1
* Retain compatibility with NEOS v1
Version 0.2.8 (2017-02-27)
===========================
* Fix bug where frames were being dropped in minute 71
* Fix bug where frames were being dropped in minute 71
Version 0.2.7 (2017-02-08)
===========================
* Better performance and pictures at night
* Fix ptr alignment issue in boardd
* Fix brake error light, fix crash if too cold
* Better performance and pictures at night
* Fix ptr alignment issue in boardd
* Fix brake error light, fix crash if too cold
Version 0.2.6 (2017-01-31)
===========================
* Fix bug in visiond model execution
* Fix bug in visiond model execution
Version 0.2.5 (2017-01-30)
===========================
* Fix race condition in manager
* Fix race condition in manager
Version 0.2.4 (2017-01-27)
===========================
* OnePlus 3T support
* Enable installation as NEOS app
* Various minor bugfixes
* OnePlus 3T support
* Enable installation as NEOS app
* Various minor bugfixes
Version 0.2.3 (2017-01-11)
===========================
* Reduce space usage by 80%
* Add better logging
* Add Travis CI
* Reduce space usage by 80%
* Add better logging
* Add Travis CI
Version 0.2.2 (2017-01-10)
===========================
* Board triggers started signal on CAN messages
* Improved autoexposure
* Handle out of space, improve upload status
* Board triggers started signal on CAN messages
* Improved autoexposure
* Handle out of space, improve upload status
Version 0.2.1 (2016-12-14)
===========================
* Performance improvements, removal of more numpy
* Fix boardd process priority
* Make counter timer reset on use of steering wheel
* Performance improvements, removal of more numpy
* Fix boardd process priority
* Make counter timer reset on use of steering wheel
Version 0.2 (2016-12-12)
=========================
* Car/Radar abstraction layers have shipped, see cereal/car.capnp
* controlsd has been refactored
* Shipped plant model and testing maneuvers
* visiond exits more gracefully now
* Hardware encoder in visiond should always init
* ui now turns off the screen after 30 seconds
* Switch to openpilot release branch for future releases
* Added preliminary Docker container to run tests on PC
* Car/Radar abstraction layers have shipped, see cereal/car.capnp
* controlsd has been refactored
* Shipped plant model and testing maneuvers
* visiond exits more gracefully now
* Hardware encoder in visiond should always init
* ui now turns off the screen after 30 seconds
* Switch to openpilot release branch for future releases
* Added preliminary Docker container to run tests on PC
Version 0.1 (2016-11-29)
=========================
* Initial release of openpilot
* Adaptive cruise control is working
* Lane keep assist is working
* Support for Acura ILX 2016 with AcuraWatch Plus
* Support for Honda Civic 2016 Touring Edition
* Initial release of openpilot
* Adaptive cruise control is working
* Lane keep assist is working
* Support for Acura ILX 2016 with AcuraWatch Plus
* Support for Honda Civic 2016 Touring Edition

View File

@ -7,6 +7,7 @@ import sys
import platform
TICI = os.path.isfile('/TICI')
Decider('MD5-timestamp')
AddOption('--test',
action='store_true',
@ -27,7 +28,7 @@ if platform.system() == "Darwin":
if arch == "aarch64" and TICI:
arch = "larch64"
webcam = bool(ARGUMENTS.get("use_webcam", 0))
USE_WEBCAM = os.getenv("USE_WEBCAM") is not None
QCOM_REPLAY = arch == "aarch64" and os.getenv("QCOM_REPLAY") is not None
if arch == "aarch64" or arch == "larch64":
@ -108,6 +109,7 @@ else:
]
rpath = [
"phonelibs/snpe/x86_64-linux-clang",
"external/tensorflow/lib",
"cereal",
"selfdrive/common"
@ -136,6 +138,7 @@ env = Environment(
"-Werror",
"-Wno-unknown-warning-option",
"-Wno-deprecated-register",
"-Wno-register",
"-Wno-inconsistent-missing-override",
"-Wno-c99-designator",
"-Wno-reorder-init-list",
@ -175,7 +178,7 @@ env = Environment(
RPATH=rpath,
CFLAGS=["-std=gnu11"] + cflags,
CXXFLAGS=["-std=c++14"] + cxxflags,
CXXFLAGS=["-std=c++1z"] + cxxflags,
LIBPATH=libpath + [
"#cereal",
"#selfdrive/common",
@ -200,6 +203,7 @@ if arch in ["x86_64", "Darwin", "larch64"]:
]
qt_env["LINKFLAGS"] += ["-F" + QT_BASE + "lib"]
else:
qt_env['QTDIR'] = "/usr"
qt_dirs = [
f"/usr/include/{real_arch}-linux-gnu/qt5",
f"/usr/include/{real_arch}-linux-gnu/qt5/QtWidgets",
@ -259,7 +263,7 @@ def abspath(x):
# still needed for apks
zmq = 'zmq'
Export('env', 'qt_env', 'arch', 'zmq', 'SHARED', 'webcam', 'QCOM_REPLAY')
Export('env', 'qt_env', 'arch', 'zmq', 'SHARED', 'USE_WEBCAM', 'QCOM_REPLAY')
# cereal and messaging are shared with the system
SConscript(['cereal/SConscript'])

Binary file not shown.

View File

@ -25,7 +25,6 @@ struct CarEvent @0x9b1657f34caf3ad3 {
canError @0;
steerUnavailable @1;
brakeUnavailable @2;
gasUnavailable @3;
wrongGear @4;
doorOpen @5;
seatbeltNotLatched @6;
@ -98,12 +97,12 @@ struct CarEvent @0x9b1657f34caf3ad3 {
whitePandaUnsupported @81;
belowEngageSpeed @84;
noGps @85;
focusRecoverActive @86;
wrongCruiseMode @87;
neosUpdateRequired @88;
modeldLagging @89;
deviceFalling @90;
fanMalfunction @91;
gasUnavailableDEPRECATED @3;
dataNeededDEPRECATED @16;
modelCommIssueDEPRECATED @27;
ipasOverrideDEPRECATED @33;
@ -114,6 +113,8 @@ struct CarEvent @0x9b1657f34caf3ad3 {
invalidGiraffeHondaDEPRECATED @49;
canErrorPersistentDEPRECATED @83;
startupWhitePandaDEPRECATED @82;
focusRecoverActiveDEPRECATED @86;
neosUpdateRequiredDEPRECATED @88;
}
}

View File

@ -571,7 +571,7 @@ struct ControlsState @0x97ff69c53601abf1 {
enum AlertStatus {
normal @0; # low priority alert for user's convenience
userPrompt @1; # mid piority alert that might require user intervention
userPrompt @1; # mid priority alert that might require user intervention
critical @2; # high priority alert that needs immediate user intervention
}
@ -1983,6 +1983,7 @@ struct Boot {
wallTimeNanos @0 :UInt64;
lastKmsg @1 :Data;
lastPmsg @2 :Data;
launchLog @3 :Text;
}
struct LiveParametersData {

View File

@ -140,9 +140,9 @@ cdef class PubSocket:
else:
raise MessagingError
def send(self, string data):
def send(self, bytes data):
length = len(data)
r = self.socket.send(<char*>data.c_str(), length)
r = self.socket.send(<char*>data, length)
if r != length:
if errno.errno == errno.EADDRINUSE:

View File

@ -31,7 +31,7 @@ class BuildExtWithoutPlatformSuffix(build_ext):
sourcefiles = ['messaging_pyx.pyx']
extra_compile_args = ["-std=c++14", "-Wno-nullability-completeness"]
extra_compile_args = ["-std=c++1z", "-Wno-nullability-completeness"]
libraries = ['zmq']
ARCH = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip() # pylint: disable=unexpected-keyword-arg

View File

@ -114,6 +114,7 @@ int msgq_new_queue(msgq_queue_t * q, const char * path, size_t size){
int rc = ftruncate(fd, size + sizeof(msgq_header_t));
if (rc < 0){
close(fd);
return -1;
}
char * mem = (char*)mmap(NULL, size + sizeof(msgq_header_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);

View File

@ -4,3 +4,11 @@ Import('env', 'cython_dependencies')
env.Command(['common_pyx.so', 'clock.cpp'],
cython_dependencies + ['common_pyx_setup.py', 'clock.pyx'],
"cd common && python3 common_pyx_setup.py build_ext --inplace")
# Build cython params module
env.Command(['params_pyx.so', 'params_pyx.cpp'],
cython_dependencies + [
'params_pyx_setup.py', 'params_pyx.pyx', 'params_pxd.pxd',
'#selfdrive/common/params.cc', '#selfdrive/common/params.h',
'#selfdrive/common/util.c', '#selfdrive/common/util.h'],
"cd common && python3 params_pyx_setup.py build_ext --inplace")

View File

@ -31,9 +31,17 @@ def start_offroad():
system("am start -n ai.comma.plus.offroad/.MainActivity")
def set_package_permissions():
pm_grant("ai.comma.plus.offroad", "android.permission.ACCESS_FINE_LOCATION")
pm_grant("ai.comma.plus.offroad", "android.permission.READ_PHONE_STATE")
pm_grant("ai.comma.plus.offroad", "android.permission.READ_EXTERNAL_STORAGE")
try:
output = subprocess.check_output(['dumpsys', 'package', 'ai.comma.plus.offroad'], encoding="utf-8")
given_permissions = output.split("runtime permissions")[1]
except Exception:
given_permissions = ""
wanted_permissions = ["ACCESS_FINE_LOCATION", "READ_PHONE_STATE", "READ_EXTERNAL_STORAGE"]
for permission in wanted_permissions:
if permission not in given_permissions:
pm_grant("ai.comma.plus.offroad", "android.permission."+permission)
appops_set("ai.comma.plus.offroad", "SU", "allow")
appops_set("ai.comma.plus.offroad", "WIFI_SCAN", "allow")

View File

@ -4,7 +4,5 @@ BASEDIR = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__
from common.hardware import PC
if PC:
PERSIST = os.path.join(BASEDIR, "persist")
PARAMS = os.path.join(BASEDIR, "persist", "params")
else:
PERSIST = "/persist"
PARAMS = "/data/params"

View File

@ -1,3 +1,4 @@
# cython: language_level = 3
from posix.time cimport clock_gettime, timespec, CLOCK_MONOTONIC_RAW, clockid_t
IF UNAME_SYSNAME == "Darwin":

View File

@ -4,9 +4,9 @@ from Cython.Build import cythonize
from common.cython_hacks import BuildExtWithoutPlatformSuffix
sourcefiles = ['clock.pyx']
extra_compile_args = ["-std=c++11"]
extra_compile_args = ["-std=c++1z"]
setup(name='Common',
setup(name='common',
cmdclass={'build_ext': BuildExtWithoutPlatformSuffix},
ext_modules=cythonize(
Extension(
@ -14,7 +14,7 @@ setup(name='Common',
language="c++",
sources=sourcefiles,
extra_compile_args=extra_compile_args,
)
),
nthreads=4,
),
nthreads=4,
)

View File

@ -44,7 +44,7 @@ def compile_code(name, c_code, c_header, directory, cflags="", libraries=None):
ffibuilder = FFI()
ffibuilder.set_source(name, c_code, source_extension='.cpp', libraries=libraries)
ffibuilder.cdef(c_header)
os.environ['OPT'] = "-fwrapv -O2 -DNDEBUG -std=c++11"
os.environ['OPT'] = "-fwrapv -O2 -DNDEBUG -std=c++1z"
os.environ['CFLAGS'] = cflags
ffibuilder.compile(verbose=True, debug=False, tmpdir=directory)

View File

@ -2,6 +2,7 @@ import serial
from common.hardware_base import HardwareBase
from cereal import log
import subprocess
NetworkType = log.ThermalData.NetworkType
@ -40,7 +41,7 @@ class Tici(HardwareBase):
return ""
def reboot(self, reason=None):
print("REBOOT!")
subprocess.check_output(["sudo", "reboot"])
def get_network_type(self):
return NetworkType.wifi

View File

@ -1,3 +1,5 @@
# cython: language_level = 3
cdef class KF1D:
cdef public:
double x0_0
@ -13,4 +15,4 @@ cdef class KF1D:
double A_K_0
double A_K_1
double A_K_2
double A_K_3
double A_K_3

View File

@ -6,4 +6,5 @@ from common.cython_hacks import BuildExtWithoutPlatformSuffix
setup(name='Simple Kalman Implementation',
cmdclass={'build_ext': BuildExtWithoutPlatformSuffix},
ext_modules=cythonize(Extension("simple_kalman_impl", ["simple_kalman_impl.pyx"])))
ext_modules=cythonize(Extension("simple_kalman_impl",
["simple_kalman_impl.pyx"])))

413
common/params.py 100755 → 100644
View File

@ -1,409 +1,4 @@
#!/usr/bin/env python3
"""ROS has a parameter server, we have files.
The parameter store is a persistent key value store, implemented as a directory with a writer lock.
On Android, we store params under params_dir = /data/params. The writer lock is a file
"<params_dir>/.lock" taken using flock(), and data is stored in a directory symlinked to by
"<params_dir>/d".
Each key, value pair is stored as a file with named <key> with contents <value>, located in
<params_dir>/d/<key>
Readers of a single key can just open("<params_dir>/d/<key>") and read the file contents.
Readers who want a consistent snapshot of multiple keys should take the lock.
Writers should take the lock before modifying anything. Writers should also leave the DB in a
consistent state after a crash. The implementation below does this by copying all params to a temp
directory <params_dir>/<tmp>, then atomically symlinking <params_dir>/<d> to <params_dir>/<tmp>
before deleting the old <params_dir>/<d> directory.
Writers that only modify a single key can simply take the lock, then swap the corresponding value
file in place without messing with <params_dir>/d.
"""
import time
import os
import errno
import shutil
import fcntl
import tempfile
import threading
from enum import Enum
from common.basedir import PARAMS
def mkdirs_exists_ok(path):
try:
os.makedirs(path)
except OSError:
if not os.path.isdir(path):
raise
class TxType(Enum):
PERSISTENT = 1
CLEAR_ON_MANAGER_START = 2
CLEAR_ON_PANDA_DISCONNECT = 3
class UnknownKeyName(Exception):
pass
keys = {
"AccessToken": [TxType.CLEAR_ON_MANAGER_START],
"AthenadPid": [TxType.PERSISTENT],
"CalibrationParams": [TxType.PERSISTENT],
"CarBatteryCapacity": [TxType.PERSISTENT],
"CarParams": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT],
"CarParamsCache": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT],
"CarVin": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT],
"CommunityFeaturesToggle": [TxType.PERSISTENT],
"CompletedTrainingVersion": [TxType.PERSISTENT],
"DisablePowerDown": [TxType.PERSISTENT],
"DisableUpdates": [TxType.PERSISTENT],
"DoUninstall": [TxType.CLEAR_ON_MANAGER_START],
"DongleId": [TxType.PERSISTENT],
"GitBranch": [TxType.PERSISTENT],
"GitCommit": [TxType.PERSISTENT],
"GitRemote": [TxType.PERSISTENT],
"GithubSshKeys": [TxType.PERSISTENT],
"HasAcceptedTerms": [TxType.PERSISTENT],
"HasCompletedSetup": [TxType.PERSISTENT],
"IsDriverViewEnabled": [TxType.CLEAR_ON_MANAGER_START],
"IsLdwEnabled": [TxType.PERSISTENT],
"IsMetric": [TxType.PERSISTENT],
"IsOffroad": [TxType.CLEAR_ON_MANAGER_START],
"IsRHD": [TxType.PERSISTENT],
"IsTakingSnapshot": [TxType.CLEAR_ON_MANAGER_START],
"IsUpdateAvailable": [TxType.CLEAR_ON_MANAGER_START],
"IsUploadRawEnabled": [TxType.PERSISTENT],
"LastAthenaPingTime": [TxType.PERSISTENT],
"LastUpdateTime": [TxType.PERSISTENT],
"LastUpdateException": [TxType.PERSISTENT],
"LiveParameters": [TxType.PERSISTENT],
"OpenpilotEnabledToggle": [TxType.PERSISTENT],
"LaneChangeEnabled": [TxType.PERSISTENT],
"PandaFirmware": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT],
"PandaFirmwareHex": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT],
"PandaDongleId": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT],
"Passive": [TxType.PERSISTENT],
"RecordFront": [TxType.PERSISTENT],
"ReleaseNotes": [TxType.PERSISTENT],
"ShouldDoUpdate": [TxType.CLEAR_ON_MANAGER_START],
"SubscriberInfo": [TxType.PERSISTENT],
"TermsVersion": [TxType.PERSISTENT],
"TrainingVersion": [TxType.PERSISTENT],
"UpdateAvailable": [TxType.CLEAR_ON_MANAGER_START],
"UpdateFailedCount": [TxType.CLEAR_ON_MANAGER_START],
"Version": [TxType.PERSISTENT],
"Offroad_ChargeDisabled": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT],
"Offroad_ConnectivityNeeded": [TxType.CLEAR_ON_MANAGER_START],
"Offroad_ConnectivityNeededPrompt": [TxType.CLEAR_ON_MANAGER_START],
"Offroad_TemperatureTooHigh": [TxType.CLEAR_ON_MANAGER_START],
"Offroad_PandaFirmwareMismatch": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT],
"Offroad_InvalidTime": [TxType.CLEAR_ON_MANAGER_START],
"Offroad_IsTakingSnapshot": [TxType.CLEAR_ON_MANAGER_START],
"Offroad_NeosUpdate": [TxType.CLEAR_ON_MANAGER_START],
"Offroad_UpdateFailed": [TxType.CLEAR_ON_MANAGER_START],
}
def fsync_dir(path):
fd = os.open(path, os.O_RDONLY)
try:
os.fsync(fd)
finally:
os.close(fd)
class FileLock():
def __init__(self, path, create, lock_ex):
self._path = path
self._create = create
self._fd = None
self._lock_ex = lock_ex
def acquire(self):
self._fd = os.open(self._path, os.O_CREAT if self._create else 0)
fcntl.flock(self._fd, fcntl.LOCK_EX if self._lock_ex else fcntl.LOCK_SH)
def release(self):
if self._fd is not None:
os.close(self._fd)
self._fd = None
class DBAccessor():
def __init__(self, path):
self._path = path
self._vals = None
def keys(self):
self._check_entered()
return self._vals.keys()
def get(self, key):
self._check_entered()
if self._vals is None:
return None
try:
return self._vals[key]
except KeyError:
return None
def _get_lock(self, create, lock_ex):
lock = FileLock(os.path.join(self._path, ".lock"), create, lock_ex)
lock.acquire()
return lock
def _read_values_locked(self):
"""Callers should hold a lock while calling this method."""
vals = {}
try:
data_path = self._data_path()
keys = os.listdir(data_path)
for key in keys:
with open(os.path.join(data_path, key), "rb") as f:
vals[key] = f.read()
except (OSError, IOError) as e:
# Either the DB hasn't been created yet, or somebody wrote a bug and left the DB in an
# inconsistent state. Either way, return empty.
if e.errno == errno.ENOENT:
return {}
return vals
def _data_path(self):
return os.path.join(self._path, "d")
def _check_entered(self):
if self._vals is None:
raise Exception("Must call __enter__ before using DB")
class DBReader(DBAccessor):
def __enter__(self):
try:
lock = self._get_lock(False, False)
except OSError as e:
# Do not create lock if it does not exist.
if e.errno == errno.ENOENT:
self._vals = {}
return self
try:
# Read everything.
self._vals = self._read_values_locked()
return self
finally:
lock.release()
def __exit__(self, exc_type, exc_value, traceback):
pass
class DBWriter(DBAccessor):
def __init__(self, path):
super(DBWriter, self).__init__(path)
self._lock = None
self._prev_umask = None
def put(self, key, value):
self._vals[key] = value
def delete(self, key):
self._vals.pop(key, None)
def __enter__(self):
mkdirs_exists_ok(self._path)
# Make sure we can write and that permissions are correct.
self._prev_umask = os.umask(0)
try:
os.chmod(self._path, 0o777)
self._lock = self._get_lock(True, True)
self._vals = self._read_values_locked()
except Exception:
os.umask(self._prev_umask)
self._prev_umask = None
raise
return self
def __exit__(self, exc_type, exc_value, traceback):
self._check_entered()
try:
# data_path refers to the externally used path to the params. It is a symlink.
# old_data_path is the path currently pointed to by data_path.
# tempdir_path is a path where the new params will go, which the new data path will point to.
# new_data_path is a temporary symlink that will atomically overwrite data_path.
#
# The current situation is:
# data_path -> old_data_path
# We're going to write params data to tempdir_path
# tempdir_path -> params data
# Then point new_data_path to tempdir_path
# new_data_path -> tempdir_path
# Then atomically overwrite data_path with new_data_path
# data_path -> tempdir_path
old_data_path = None
new_data_path = None
tempdir_path = tempfile.mkdtemp(prefix=".tmp", dir=self._path)
try:
# Write back all keys.
os.chmod(tempdir_path, 0o777)
for k, v in self._vals.items():
with open(os.path.join(tempdir_path, k), "wb") as f:
f.write(v)
f.flush()
os.fsync(f.fileno())
fsync_dir(tempdir_path)
data_path = self._data_path()
try:
old_data_path = os.path.join(self._path, os.readlink(data_path))
except (OSError, IOError):
# NOTE(mgraczyk): If other DB implementations have bugs, this could cause
# copies to be left behind, but we still want to overwrite.
pass
new_data_path = "{}.link".format(tempdir_path)
os.symlink(os.path.basename(tempdir_path), new_data_path)
os.rename(new_data_path, data_path)
fsync_dir(self._path)
finally:
# If the rename worked, we can delete the old data. Otherwise delete the new one.
success = new_data_path is not None and os.path.exists(data_path) and (
os.readlink(data_path) == os.path.basename(tempdir_path))
if success:
if old_data_path is not None:
shutil.rmtree(old_data_path)
else:
shutil.rmtree(tempdir_path)
# Regardless of what happened above, there should be no link at new_data_path.
if new_data_path is not None and os.path.islink(new_data_path):
os.remove(new_data_path)
finally:
os.umask(self._prev_umask)
self._prev_umask = None
# Always release the lock.
self._lock.release()
self._lock = None
def read_db(params_path, key):
path = "%s/d/%s" % (params_path, key)
try:
with open(path, "rb") as f:
return f.read()
except IOError:
return None
def write_db(params_path, key, value):
if isinstance(value, str):
value = value.encode('utf8')
prev_umask = os.umask(0)
lock = FileLock(params_path + "/.lock", True, True)
lock.acquire()
try:
tmp_path = tempfile.NamedTemporaryFile(mode="wb", prefix=".tmp", dir=params_path, delete=False)
with tmp_path as f:
f.write(value)
f.flush()
os.fsync(f.fileno())
os.chmod(tmp_path.name, 0o666)
path = "%s/d/%s" % (params_path, key)
os.rename(tmp_path.name, path)
fsync_dir(os.path.dirname(path))
finally:
os.umask(prev_umask)
lock.release()
class Params():
def __init__(self, db=PARAMS):
self.db = db
# create the database if it doesn't exist...
if not os.path.exists(self.db + "/d"):
with self.transaction(write=True):
pass
def clear_all(self):
shutil.rmtree(self.db, ignore_errors=True)
with self.transaction(write=True):
pass
def transaction(self, write=False):
if write:
return DBWriter(self.db)
else:
return DBReader(self.db)
def _clear_keys_with_type(self, tx_type):
with self.transaction(write=True) as txn:
for key in keys:
if tx_type in keys[key]:
txn.delete(key)
def manager_start(self):
self._clear_keys_with_type(TxType.CLEAR_ON_MANAGER_START)
def panda_disconnect(self):
self._clear_keys_with_type(TxType.CLEAR_ON_PANDA_DISCONNECT)
def delete(self, key):
with self.transaction(write=True) as txn:
txn.delete(key)
def get(self, key, block=False, encoding=None):
if key not in keys:
raise UnknownKeyName(key)
while 1:
ret = read_db(self.db, key)
if not block or ret is not None:
break
# is polling really the best we can do?
time.sleep(0.05)
if ret is not None and encoding is not None:
ret = ret.decode(encoding)
return ret
def put(self, key, dat):
"""
Warning: This function blocks until the param is written to disk!
In very rare cases this can take over a second, and your code will hang.
Use the put_nonblocking helper function in time sensitive code, but
in general try to avoid writing params as much as possible.
"""
if key not in keys:
raise UnknownKeyName(key)
write_db(self.db, key, dat)
def put_nonblocking(key, val):
def f(key, val):
params = Params()
params.put(key, val)
t = threading.Thread(target=f, args=(key, val))
t.start()
return t
from common.params_pyx import Params, UnknownKeyName, put_nonblocking # pylint: disable=no-name-in-module, import-error
assert Params
assert UnknownKeyName
assert put_nonblocking

View File

@ -0,0 +1,16 @@
from libcpp.string cimport string
from libcpp cimport bool
cdef extern from "selfdrive/common/params.cc":
pass
cdef extern from "selfdrive/common/util.c":
pass
cdef extern from "selfdrive/common/params.h":
cdef cppclass Params:
Params(bool)
Params(string)
string get(string, bool) nogil
int delete_db_value(string)
int write_db_value(string, string)

View File

@ -0,0 +1,160 @@
# distutils: language = c++
# cython: language_level = 3
from libcpp cimport bool
from libcpp.string cimport string
from params_pxd cimport Params as c_Params
import os
import threading
from common.basedir import BASEDIR
cdef enum TxType:
PERSISTENT = 1
CLEAR_ON_MANAGER_START = 2
CLEAR_ON_PANDA_DISCONNECT = 3
keys = {
b"AccessToken": [TxType.CLEAR_ON_MANAGER_START],
b"AthenadPid": [TxType.PERSISTENT],
b"CalibrationParams": [TxType.PERSISTENT],
b"CarBatteryCapacity": [TxType.PERSISTENT],
b"CarParams": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT],
b"CarParamsCache": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT],
b"CarVin": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT],
b"CommunityFeaturesToggle": [TxType.PERSISTENT],
b"CompletedTrainingVersion": [TxType.PERSISTENT],
b"DisablePowerDown": [TxType.PERSISTENT],
b"DisableUpdates": [TxType.PERSISTENT],
b"DoUninstall": [TxType.CLEAR_ON_MANAGER_START],
b"DongleId": [TxType.PERSISTENT],
b"GitBranch": [TxType.PERSISTENT],
b"GitCommit": [TxType.PERSISTENT],
b"GitRemote": [TxType.PERSISTENT],
b"GithubSshKeys": [TxType.PERSISTENT],
b"HasAcceptedTerms": [TxType.PERSISTENT],
b"HasCompletedSetup": [TxType.PERSISTENT],
b"IsDriverViewEnabled": [TxType.CLEAR_ON_MANAGER_START],
b"IsLdwEnabled": [TxType.PERSISTENT],
b"IsMetric": [TxType.PERSISTENT],
b"IsOffroad": [TxType.CLEAR_ON_MANAGER_START],
b"IsRHD": [TxType.PERSISTENT],
b"IsTakingSnapshot": [TxType.CLEAR_ON_MANAGER_START],
b"IsUpdateAvailable": [TxType.CLEAR_ON_MANAGER_START],
b"IsUploadRawEnabled": [TxType.PERSISTENT],
b"LastAthenaPingTime": [TxType.PERSISTENT],
b"LastUpdateTime": [TxType.PERSISTENT],
b"LastUpdateException": [TxType.PERSISTENT],
b"LiveParameters": [TxType.PERSISTENT],
b"OpenpilotEnabledToggle": [TxType.PERSISTENT],
b"LaneChangeEnabled": [TxType.PERSISTENT],
b"PandaFirmware": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT],
b"PandaFirmwareHex": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT],
b"PandaDongleId": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT],
b"Passive": [TxType.PERSISTENT],
b"RecordFront": [TxType.PERSISTENT],
b"ReleaseNotes": [TxType.PERSISTENT],
b"ShouldDoUpdate": [TxType.CLEAR_ON_MANAGER_START],
b"SubscriberInfo": [TxType.PERSISTENT],
b"TermsVersion": [TxType.PERSISTENT],
b"TrainingVersion": [TxType.PERSISTENT],
b"UpdateAvailable": [TxType.CLEAR_ON_MANAGER_START],
b"UpdateFailedCount": [TxType.CLEAR_ON_MANAGER_START],
b"Version": [TxType.PERSISTENT],
b"Offroad_ChargeDisabled": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT],
b"Offroad_ConnectivityNeeded": [TxType.CLEAR_ON_MANAGER_START],
b"Offroad_ConnectivityNeededPrompt": [TxType.CLEAR_ON_MANAGER_START],
b"Offroad_TemperatureTooHigh": [TxType.CLEAR_ON_MANAGER_START],
b"Offroad_PandaFirmwareMismatch": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT],
b"Offroad_InvalidTime": [TxType.CLEAR_ON_MANAGER_START],
b"Offroad_IsTakingSnapshot": [TxType.CLEAR_ON_MANAGER_START],
b"Offroad_NeosUpdate": [TxType.CLEAR_ON_MANAGER_START],
b"Offroad_UpdateFailed": [TxType.CLEAR_ON_MANAGER_START],
}
def ensure_bytes(v):
if isinstance(v, str):
return v.encode()
else:
return v
class UnknownKeyName(Exception):
pass
cdef class Params:
cdef c_Params* p
def __cinit__(self, d=None, bool persistent_params=False):
if d is None:
self.p = new c_Params(persistent_params)
else:
self.p = new c_Params(<string>d.encode())
def __dealloc__(self):
del self.p
def clear_all(self, tx_type=None):
for key in keys:
if tx_type is None or tx_type in keys[key]:
self.delete(key)
def manager_start(self):
self.clear_all(TxType.CLEAR_ON_MANAGER_START)
def panda_disconnect(self):
self.clear_all(TxType.CLEAR_ON_PANDA_DISCONNECT)
def get(self, key, block=False, encoding=None):
key = ensure_bytes(key)
if key not in keys:
raise UnknownKeyName(key)
cdef string k = key
cdef bool b = block
cdef string val
with nogil:
val = self.p.get(k, b)
if val == b"":
if block:
# If we got no value while running in blocked mode
# it means we got an interrupt while waiting
raise KeyboardInterrupt
else:
return None
if encoding is not None:
return val.decode(encoding)
else:
return val
def put(self, key, dat):
"""
Warning: This function blocks until the param is written to disk!
In very rare cases this can take over a second, and your code will hang.
Use the put_nonblocking helper function in time sensitive code, but
in general try to avoid writing params as much as possible.
"""
key = ensure_bytes(key)
dat = ensure_bytes(dat)
if key not in keys:
raise UnknownKeyName(key)
self.p.write_db_value(key, dat)
def delete(self, key):
key = ensure_bytes(key)
self.p.delete_db_value(key)
def put_nonblocking(key, val, d=None):
def f(key, val):
params = Params(d)
params.put(key, val)
t = threading.Thread(target=f, args=(key, val))
t.start()
return t

View File

@ -0,0 +1,33 @@
import os
import subprocess
from distutils.core import Extension, setup
from Cython.Build import cythonize
from common.cython_hacks import BuildExtWithoutPlatformSuffix
from common.basedir import BASEDIR
from common.hardware import TICI
ARCH = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip() # pylint: disable=unexpected-keyword-arg
sourcefiles = ['params_pyx.pyx']
extra_compile_args = ["-std=c++11"]
if ARCH == "aarch64":
if TICI:
extra_compile_args += ["-DQCOM2"]
else:
extra_compile_args += ["-DQCOM"]
setup(name='common',
cmdclass={'build_ext': BuildExtWithoutPlatformSuffix},
ext_modules=cythonize(
Extension(
"params_pyx",
language="c++",
sources=sourcefiles,
include_dirs=[BASEDIR, os.path.join(BASEDIR, 'selfdrive')],
extra_compile_args=extra_compile_args
)
)
)

View File

@ -36,10 +36,10 @@ class Profiler():
if not self.enabled:
return
self.iter += 1
print("******* Profiling *******")
print("******* Profiling %d *******" % self.iter)
for n, ms in sorted(self.cp.items(), key=lambda x: -x[1]):
if n in self.cp_ignored:
print("%30s: %9.2f percent: %3.0f IGNORED" % (n, ms*1000.0, ms/self.tot*100))
print("%30s: %9.2f avg: %7.2f percent: %3.0f IGNORED" % (n, ms*1000.0, ms*1000.0/self.iter, ms/self.tot*100))
else:
print("%30s: %9.2f percent: %3.0f" % (n, ms*1000.0, ms/self.tot*100))
print("%30s: %9.2f avg: %7.2f percent: %3.0f" % (n, ms*1000.0, ms*1000.0/self.iter, ms/self.tot*100))
print("Iter clock: %2.6f TOTAL: %2.2f" % (self.tot/self.iter, self.tot))

View File

@ -31,7 +31,7 @@ def set_core_affinity(core):
os.sched_setaffinity(0, [core,])
def config_rt_process(core, priority):
def config_realtime_process(core, priority):
gc.disable()
set_realtime_priority(priority)
set_core_affinity(core)

View File

@ -1,42 +1,20 @@
import os
import numpy
import sysconfig
from Cython.Build import cythonize
from Cython.Distutils import build_ext
from distutils.core import Extension, setup # pylint: disable=import-error,no-name-in-module
def get_ext_filename_without_platform_suffix(filename):
name, ext = os.path.splitext(filename)
ext_suffix = sysconfig.get_config_var('EXT_SUFFIX')
if ext_suffix == ext:
return filename
ext_suffix = ext_suffix.replace(ext, '')
idx = name.find(ext_suffix)
if idx == -1:
return filename
else:
return name[:idx] + ext
class BuildExtWithoutPlatformSuffix(build_ext):
def get_ext_filename(self, ext_name):
filename = super().get_ext_filename(ext_name)
return get_ext_filename_without_platform_suffix(filename)
from common.cython_hacks import BuildExtWithoutPlatformSuffix
setup(
name='Cython transformations wrapper',
cmdclass={'build_ext': BuildExtWithoutPlatformSuffix},
ext_modules=cythonize(
Extension(
"transformations",
sources=["transformations.pyx"],
language="c++",
extra_compile_args=["-std=c++14"],
include_dirs=[numpy.get_include()],
Extension(
"transformations",
sources=["transformations.pyx"],
language="c++",
extra_compile_args=["-std=c++1z", "-Wno-cpp"],
include_dirs=[numpy.get_include()],
),
nthreads=4,
)
))
)

View File

@ -1,3 +1,4 @@
#cython: language_level=3
from libcpp cimport bool
cdef extern from "orientation.cc":

View File

@ -26,7 +26,7 @@ cdef np.ndarray[double, ndim=2] matrix2numpy(Matrix3 m):
[m(2, 0), m(2, 1), m(2, 2)],
])
cdef Matrix3 numpy2matrix (np.ndarray[double, ndim=2, mode="fortran"] m):
cdef Matrix3 numpy2matrix(np.ndarray[double, ndim=2, mode="fortran"] m):
assert m.shape[0] == 3
assert m.shape[1] == 3
return Matrix3(<double*>m.data)

View File

@ -10,7 +10,7 @@ WARN_FLAGS = -Werror=implicit-function-declaration \
-Werror=format-extra-args
CFLAGS = -std=gnu11 -g -fPIC -O2 $(WARN_FLAGS)
CXXFLAGS = -std=c++11 -g -fPIC -O2 $(WARN_FLAGS)
CXXFLAGS = -std=c++1z -g -fPIC -O2 $(WARN_FLAGS)
CURL_FLAGS = -I$(PHONELIBS)/curl/include
CURL_LIBS = $(PHONELIBS)/curl/lib/libcurl.a \
@ -34,6 +34,7 @@ all: updater
OBJS = opensans_regular.ttf.o \
opensans_semibold.ttf.o \
opensans_bold.ttf.o \
../../selfdrive/common/util.o \
../../selfdrive/common/touch.o \
../../selfdrive/common/framebuffer.o \
$(PHONELIBS)/json11/json11.o \

View File

@ -1,7 +1,7 @@
{
"ota_url": "https://commadist.azureedge.net/neosupdate/ota-signed-efdf7de63b1aef63d68301e6175930991bf9a5927d16ec6fcc69287e2ee7ca4a.zip",
"ota_hash": "efdf7de63b1aef63d68301e6175930991bf9a5927d16ec6fcc69287e2ee7ca4a",
"recovery_url": "https://commadist.azureedge.net/neosupdate/recovery-97c27e6ed04ed6bb0608b845a2d4100912093f9380c3f2ba6b56bccd608e5f6e.img",
"recovery_len": 15861036,
"recovery_hash": "97c27e6ed04ed6bb0608b845a2d4100912093f9380c3f2ba6b56bccd608e5f6e"
"ota_url": "https://commadist.azureedge.net/neosupdate/ota-signed-ba3ecb158edc760beda0d32e0eea4311031e460afa97fc180dc83f76cf512694.zip",
"ota_hash": "ba3ecb158edc760beda0d32e0eea4311031e460afa97fc180dc83f76cf512694",
"recovery_url": "https://commadist.azureedge.net/neosupdate/recovery-e35dc1939dab4c6c2cbae3f225b07515f1a5c02afb232dc22e93f17c9840499f.img",
"recovery_len": 15926572,
"recovery_hash": "e35dc1939dab4c6c2cbae3f225b07515f1a5c02afb232dc22e93f17c9840499f"
}

View File

@ -1,7 +0,0 @@
{
"ota_url": "https://commadist.azureedge.net/neosupdate/ota-signed-3bd2b3bdd6a501569e00b8f12786d65e0fd2788c0dd238f8c986e3e2e504683a-kernel.zip",
"ota_hash": "3bd2b3bdd6a501569e00b8f12786d65e0fd2788c0dd238f8c986e3e2e504683a",
"recovery_url": "https://commadist.azureedge.net/neosupdate/recovery-97c27e6ed04ed6bb0608b845a2d4100912093f9380c3f2ba6b56bccd608e5f6e.img",
"recovery_len": 15861036,
"recovery_hash": "97c27e6ed04ed6bb0608b845a2d4100912093f9380c3f2ba6b56bccd608e5f6e"
}

Binary file not shown.

View File

@ -231,6 +231,8 @@ struct Updater {
&fb_w, &fb_h);
assert(fb);
framebuffer_set_power(fb, HWC_POWER_MODE_NORMAL);
vg = nvgCreateGLES3(NVG_ANTIALIAS | NVG_STENCIL_STROKES | NVG_DEBUG);
assert(vg);

View File

@ -12,8 +12,8 @@ function two_init {
# Restrict Android and other system processes to the first two cores
echo 0-1 > /dev/cpuset/background/cpus
echo 0-1 > /dev/cpuset/system-background/cpus
echo 0-1 > /dev/cpuset/foreground/boost/cpus
echo 0-1 > /dev/cpuset/foreground/cpus
echo 0-1 > /dev/cpuset/foreground/boost/cpus
echo 0-1 > /dev/cpuset/android/cpus
# openpilot gets all the cores
@ -27,6 +27,8 @@ function two_init {
[ -d "/proc/irq/733" ] && echo 3 > /proc/irq/733/smp_affinity_list # USB for LeEco
[ -d "/proc/irq/736" ] && echo 3 > /proc/irq/736/smp_affinity_list # USB for OP3T
# restrict unbound kworkers to first two cores
#find /sys/devices/virtual/workqueue -name cpumask -exec sh -c 'echo 3 > {}' ';'
# Check for NEOS update
if [ $(< /VERSION) != "$REQUIRED_NEOS_VERSION" ]; then
@ -43,10 +45,6 @@ function two_init {
fi
"$DIR/installer/updater/updater" "file://$DIR/installer/updater/update.json"
else
if [[ $(uname -v) == "#1 SMP PREEMPT Wed Jun 10 12:40:53 PDT 2020" ]]; then
"$DIR/installer/updater/updater" "file://$DIR/installer/updater/update_kernel.json"
fi
fi
# One-time fix for a subset of OP3T with gyro orientation offsets.
@ -117,6 +115,9 @@ function launch {
ln -sfn $(pwd) /data/pythonpath
export PYTHONPATH="$PWD"
# write tmux scrollback to a file
tmux capture-pane -pq -S-1000 > /tmp/launch_log
# start manager
cd selfdrive
./manager.py

View File

@ -7,7 +7,7 @@ export OPENBLAS_NUM_THREADS=1
export VECLIB_MAXIMUM_THREADS=1
if [ -z "$REQUIRED_NEOS_VERSION" ]; then
export REQUIRED_NEOS_VERSION="14"
export REQUIRED_NEOS_VERSION="15"
fi
if [ -z "$PASSIVE" ]; then

View File

@ -0,0 +1,433 @@
CM_ "AUTOGENERATED FILE, DO NOT EDIT"
CM_ "Imported file _bosch_2020.dbc starts here"
VERSION ""
NS_ :
NS_DESC_
CM_
BA_DEF_
BA_
VAL_
CAT_DEF_
CAT_
FILTER
BA_DEF_DEF_
EV_DATA_
ENVVAR_DATA_
SGTYPE_
SGTYPE_VAL_
BA_DEF_SGTYPE_
BA_SGTYPE_
SIG_TYPE_REF_
VAL_TABLE_
SIG_GROUP_
SIG_VALTYPE_
SIGTYPE_VALTYPE_
BO_TX_BU_
BA_DEF_REL_
BA_REL_
BA_DEF_DEF_REL_
BU_SG_REL_
BU_EV_REL_
BU_BO_REL_
SG_MUL_VAL_
BU_: EBCM EON CAM RADAR PCM EPS VSA SCM BDY XXX EPB
BO_ 148 KINEMATICS: 8 XXX
SG_ LAT_ACCEL : 7|10@0+ (-0.035,17.92) [-20|20] "m/s2" EON
SG_ LONG_ACCEL : 25|10@0+ (-0.035,17.92) [-20|20] "m/s2" EON
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON
BO_ 228 STEERING_CONTROL: 5 EON
SG_ STEER_TORQUE_REQUEST : 23|1@0+ (1,0) [0|1] "" EPS
SG_ SET_ME_X00 : 22|7@0+ (1,0) [0|127] "" EPS
SG_ SET_ME_X00_2 : 31|8@0+ (1,0) [0|0] "" EPS
SG_ STEER_TORQUE : 7|16@0- (1,0) [-4096|4096] "" EPS
SG_ COUNTER : 37|2@0+ (1,0) [0|3] "" EPS
SG_ CHECKSUM : 35|4@0+ (1,0) [0|15] "" EPS
BO_ 229 BOSCH_SUPPLEMENTAL_1: 8 XXX
SG_ SET_ME_X04 : 0|8@1+ (1,0) [0|255] "" XXX
SG_ SET_ME_X00 : 8|8@1+ (1,0) [0|255] "" XXX
SG_ SET_ME_X80 : 16|8@1+ (1,0) [0|255] "" XXX
SG_ SET_ME_X10 : 24|8@1+ (1,0) [0|255] "" XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX
SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX
BO_ 232 BRAKE_HOLD: 7 XXX
SG_ XMISSION_SPEED : 7|14@0- (1,0) [1|0] "" XXX
SG_ COMPUTER_BRAKE : 39|16@0+ (1,0) [0|0] "" XXX
SG_ COMPUTER_BRAKE_REQUEST : 29|1@0+ (1,0) [0|0] "" XXX
SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" XXX
SG_ CHECKSUM : 51|4@0+ (1,0) [0|15] "" XXX
BO_ 342 STEERING_SENSORS: 6 EPS
SG_ STEER_ANGLE : 7|16@0- (-0.1,0) [-500|500] "deg" EON
SG_ STEER_ANGLE_RATE : 23|16@0- (1,0) [-3000|3000] "deg/s" EON
SG_ COUNTER : 45|2@0+ (1,0) [0|3] "" EON
SG_ CHECKSUM : 43|4@0+ (1,0) [0|15] "" EON
BO_ 344 ENGINE_DATA: 8 PCM
SG_ XMISSION_SPEED : 7|16@0+ (0.01,0) [0|250] "kph" EON
SG_ ENGINE_RPM : 23|16@0+ (1,0) [0|15000] "rpm" EON
SG_ XMISSION_SPEED2 : 39|16@0+ (0.01,0) [0|250] "kph" EON
SG_ ODOMETER : 55|8@0+ (10,0) [0|2550] "m" XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON
SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON
BO_ 380 POWERTRAIN_DATA: 8 PCM
SG_ PEDAL_GAS : 7|8@0+ (1,0) [0|255] "" EON
SG_ ENGINE_RPM : 23|16@0+ (1,0) [0|15000] "rpm" EON
SG_ GAS_PRESSED : 39|1@0+ (1,0) [0|1] "" EON
SG_ ACC_STATUS : 38|1@0+ (1,0) [0|1] "" EON
SG_ BOH_17C : 37|5@0+ (1,0) [0|1] "" EON
SG_ BRAKE_SWITCH : 32|1@0+ (1,0) [0|1] "" EON
SG_ BOH2_17C : 47|10@0+ (1,0) [0|1] "" EON
SG_ BRAKE_PRESSED : 53|1@0+ (1,0) [0|1] "" EON
SG_ BOH3_17C : 52|5@0+ (1,0) [0|1] "" EON
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON
SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON
BO_ 399 STEER_STATUS: 7 EPS
SG_ STEER_TORQUE_SENSOR : 7|16@0- (-1,0) [-31000|31000] "tbd" EON
SG_ STEER_ANGLE_RATE : 23|16@0- (-0.1,0) [-31000|31000] "deg/s" EON
SG_ STEER_STATUS : 39|4@0+ (1,0) [0|15] "" EON
SG_ STEER_CONTROL_ACTIVE : 35|1@0+ (1,0) [0|1] "" EON
SG_ STEER_CONFIG_INDEX : 43|4@0+ (1,0) [0|15] "" EON
SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON
SG_ CHECKSUM : 51|4@0+ (1,0) [0|15] "" EON
BO_ 420 VSA_STATUS: 8 VSA
SG_ ESP_DISABLED : 28|1@0+ (1,0) [0|1] "" EON
SG_ USER_BRAKE : 7|16@0+ (0.015625,-1.609375) [0|1000] "" EON
SG_ BRAKE_HOLD_ACTIVE : 46|1@0+ (1,0) [0|1] "" EON
SG_ BRAKE_HOLD_ENABLED : 45|1@0+ (1,0) [0|1] "" EON
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON
SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON
BO_ 427 STEER_MOTOR_TORQUE: 3 EPS
SG_ CONFIG_VALID : 7|1@0+ (1,0) [0|1] "" EON
SG_ MOTOR_TORQUE : 1|10@0+ (1,0) [0|256] "" EON
SG_ OUTPUT_DISABLED : 22|1@0+ (1,0) [0|1] "" EON
SG_ COUNTER : 21|2@0+ (1,0) [0|3] "" EON
SG_ CHECKSUM : 19|4@0+ (1,0) [0|15] "" EON
BO_ 450 EPB_STATUS: 8 EPB
SG_ EPB_ACTIVE : 3|1@0+ (1,0) [0|1] "" EON
SG_ EPB_STATE : 29|2@0+ (1,0) [0|3] "" EON
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX
SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX
BO_ 464 WHEEL_SPEEDS: 8 VSA
SG_ WHEEL_SPEED_FL : 7|15@0+ (0.01,0) [0|250] "kph" EON
SG_ WHEEL_SPEED_FR : 8|15@0+ (0.01,0) [0|250] "kph" EON
SG_ WHEEL_SPEED_RL : 25|15@0+ (0.01,0) [0|250] "kph" EON
SG_ WHEEL_SPEED_RR : 42|15@0+ (0.01,0) [0|250] "kph" EON
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON
BO_ 479 ACC_CONTROL: 8 EON
SG_ SET_TO_0 : 20|5@0+ (1,0) [0|1] "" XXX
SG_ CONTROL_ON : 23|3@0+ (1,0) [0|5] "" XXX
SG_ GAS_COMMAND : 7|16@0- (1,0) [0|0] "" XXX
SG_ ACCEL_COMMAND : 31|11@0- (0.01,0) [0|0] "m/s2" XXX
SG_ BRAKE_LIGHTS : 62|1@0+ (1,0) [0|1] "" XXX
SG_ BRAKE_REQUEST : 34|1@0+ (1,0) [0|1] "" XXX
SG_ STANDSTILL : 35|1@0+ (1,0) [0|1] "" XXX
SG_ STANDSTILL_RELEASE : 36|1@0+ (1,0) [0|1] "" XXX
SG_ AEB_STATUS : 33|1@0+ (1,0) [0|1] "" XXX
SG_ AEB_BRAKING : 47|1@0+ (1,0) [0|1] "" XXX
SG_ AEB_PREPARE : 43|1@0+ (1,0) [0|1] "" XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX
SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX
BO_ 490 VEHICLE_DYNAMICS: 8 VSA
SG_ LAT_ACCEL : 7|16@0- (0.0015,0) [-20|20] "m/s2" EON
SG_ LONG_ACCEL : 23|16@0- (0.0015,0) [-20|20] "m/s2" EON
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON
BO_ 495 ACC_CONTROL_ON: 8 XXX
SG_ SET_TO_75 : 31|8@0+ (1,0) [0|255] "" XXX
SG_ SET_TO_30 : 39|8@0+ (1,0) [0|255] "" XXX
SG_ ZEROS_BOH : 23|8@0+ (1,0) [0|255] "" XXX
SG_ ZEROS_BOH2 : 47|16@0+ (1,0) [0|255] "" XXX
SG_ SET_TO_FF : 15|8@0+ (1,0) [0|255] "" XXX
SG_ SET_TO_3 : 6|7@0+ (1,0) [0|4095] "" XXX
SG_ CONTROL_ON : 7|1@0+ (1,0) [0|1] "" XXX
SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX
BO_ 545 XXX_16: 6 SCM
SG_ ECON_ON : 23|1@0+ (1,0) [0|1] "" XXX
SG_ DRIVE_MODE : 37|2@0+ (1,0) [0|3] "" XXX
SG_ COUNTER : 45|2@0+ (1,0) [0|3] "" BDY
SG_ CHECKSUM : 43|4@0+ (1,0) [0|15] "" BDY
BO_ 576 LEFT_LANE_LINE_1: 8 CAM
SG_ LINE_DISTANCE_VISIBLE : 39|9@0+ (1,0) [0|1] "" XXX
SG_ LINE_PROBABILITY : 46|6@0+ (0.015625,0) [0|1] "" XXX
SG_ LINE_OFFSET : 23|12@0+ (0.004,-8.192) [0|1] "Meters" XXX
SG_ LINE_ANGLE : 7|12@0+ (0.0005,-1.024) [0|1] "" XXX
SG_ FRAME_INDEX : 8|4@1+ (1,0) [0|15] "" XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|1] "" XXX
SG_ CHECKSUM : 59|4@0+ (1,0) [0|1] "" XXX
BO_ 577 LEFT_LANE_LINE_2: 8 CAM
SG_ LINE_FAR_EDGE_POSITION : 55|8@0+ (1,-128) [0|1] "" XXX
SG_ LINE_SOLID : 13|1@0+ (1,0) [0|1] "" XXX
SG_ LINE_DASHED : 14|1@0+ (1,0) [0|1] "" XXX
SG_ LINE_CURVATURE : 23|12@0+ (0.00001,-0.02048) [0|1] "" XXX
SG_ LINE_PARAMETER : 39|12@0+ (1,0) [0|1] "" XXX
SG_ FRAME_INDEX : 7|4@0+ (1,0) [0|15] "" XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|1] "" XXX
SG_ CHECKSUM : 59|4@0+ (1,0) [0|1] "" XXX
BO_ 579 RIGHT_LANE_LINE_1: 8 CAM
SG_ LINE_DISTANCE_VISIBLE : 39|9@0+ (1,0) [0|1] "" XXX
SG_ LINE_PROBABILITY : 46|6@0+ (0.015625,0) [0|1] "" XXX
SG_ LINE_OFFSET : 23|12@0+ (0.004,-8.192) [0|1] "Meters" XXX
SG_ LINE_ANGLE : 7|12@0+ (0.0005,-1.024) [0|1] "" XXX
SG_ FRAME_INDEX : 8|4@1+ (1,0) [0|15] "" XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|1] "" XXX
SG_ CHECKSUM : 59|4@0+ (1,0) [0|1] "" XXX
BO_ 580 RIGHT_LANE_LINE_2: 8 CAM
SG_ LINE_FAR_EDGE_POSITION : 55|8@0+ (1,-128) [0|1] "" XXX
SG_ LINE_SOLID : 13|1@0+ (1,0) [0|1] "" XXX
SG_ LINE_DASHED : 14|1@0+ (1,0) [0|1] "" XXX
SG_ LINE_CURVATURE : 23|12@0+ (0.00001,-0.02048) [0|1] "" XXX
SG_ LINE_PARAMETER : 39|12@0+ (1,0) [0|1] "" XXX
SG_ FRAME_INDEX : 7|4@0+ (1,0) [0|15] "" XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|1] "" XXX
SG_ CHECKSUM : 59|4@0+ (1,0) [0|1] "" XXX
BO_ 582 ADJACENT_LEFT_LANE_LINE_1: 8 CAM
SG_ LINE_DISTANCE_VISIBLE : 39|9@0+ (1,0) [0|1] "" XXX
SG_ LINE_PROBABILITY : 46|6@0+ (0.015625,0) [0|1] "" XXX
SG_ LINE_OFFSET : 23|12@0+ (0.004,-8.192) [0|1] "Meters" XXX
SG_ LINE_ANGLE : 7|12@0+ (0.0005,-1.024) [0|1] "" XXX
SG_ FRAME_INDEX : 8|4@1+ (1,0) [0|15] "" XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|1] "" XXX
SG_ CHECKSUM : 59|4@0+ (1,0) [0|1] "" XXX
BO_ 583 ADJACENT_LEFT_LANE_LINE_2: 8 CAM
SG_ LINE_FAR_EDGE_POSITION : 55|8@0+ (1,-128) [0|1] "" XXX
SG_ LINE_SOLID : 13|1@0+ (1,0) [0|1] "" XXX
SG_ LINE_DASHED : 14|1@0+ (1,0) [0|1] "" XXX
SG_ LINE_CURVATURE : 23|12@0+ (0.00001,-0.02048) [0|1] "" XXX
SG_ LINE_PARAMETER : 39|12@0+ (1,0) [0|1] "" XXX
SG_ FRAME_INDEX : 7|4@0+ (1,0) [0|15] "" XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|1] "" XXX
SG_ CHECKSUM : 59|4@0+ (1,0) [0|1] "" XXX
BO_ 585 ADJACENT_RIGHT_LANE_LINE_1: 8 CAM
SG_ LINE_DISTANCE_VISIBLE : 39|9@0+ (1,0) [0|1] "" XXX
SG_ LINE_PROBABILITY : 46|6@0+ (0.015625,0) [0|1] "" XXX
SG_ LINE_OFFSET : 23|12@0+ (0.004,-8.192) [0|1] "Meters" XXX
SG_ LINE_ANGLE : 7|12@0+ (0.0005,-1.024) [0|1] "" XXX
SG_ FRAME_INDEX : 8|4@1+ (1,0) [0|15] "" XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|1] "" XXX
SG_ CHECKSUM : 59|4@0+ (1,0) [0|1] "" XXX
BO_ 586 ADJACENT_RIGHT_LANE_LINE_2: 8 CAM
SG_ LINE_FAR_EDGE_POSITION : 55|8@0+ (1,-128) [0|1] "" XXX
SG_ LINE_SOLID : 13|1@0+ (1,0) [0|1] "" XXX
SG_ LINE_DASHED : 14|1@0+ (1,0) [0|1] "" XXX
SG_ LINE_CURVATURE : 23|12@0+ (0.00001,-0.02048) [0|1] "" XXX
SG_ LINE_PARAMETER : 39|12@0+ (1,0) [0|1] "" XXX
SG_ FRAME_INDEX : 7|4@0+ (1,0) [0|15] "" XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|1] "" XXX
SG_ CHECKSUM : 59|4@0+ (1,0) [0|1] "" XXX
BO_ 597 ROUGH_WHEEL_SPEED: 8 VSA
SG_ WHEEL_SPEED_FL : 7|8@0+ (1,0) [0|255] "mph" EON
SG_ WHEEL_SPEED_FR : 15|8@0+ (1,0) [0|255] "mph" EON
SG_ WHEEL_SPEED_RL : 23|8@0+ (1,0) [0|255] "mph" EON
SG_ WHEEL_SPEED_RR : 31|8@0+ (1,0) [0|255] "mph" EON
SG_ SET_TO_X55 : 39|8@0+ (1,0) [0|255] "" XXX
SG_ SET_TO_X55_2 : 47|8@0+ (1,0) [0|255] "" EON
SG_ LONG_COUNTER : 55|8@0+ (1,0) [0|255] "" XXX
SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX
BO_ 662 SCM_BUTTONS: 4 SCM
SG_ CRUISE_BUTTONS : 7|3@0+ (1,0) [0|7] "" EON
SG_ CRUISE_SETTING : 3|2@0+ (1,0) [0|3] "" EON
SG_ COUNTER : 29|2@0+ (1,0) [0|3] "" EON
SG_ CHECKSUM : 27|4@0+ (1,0) [0|15] "" EON
BO_ 773 SEATBELT_STATUS: 7 BDY
SG_ SEATBELT_DRIVER_LAMP : 7|1@0+ (1,0) [0|1] "" EON
SG_ SEATBELT_PASS_UNLATCHED : 10|1@0+ (1,0) [0|1] "" EON
SG_ SEATBELT_PASS_LATCHED : 11|1@0+ (1,0) [0|1] "" EON
SG_ SEATBELT_DRIVER_UNLATCHED : 12|1@0+ (1,0) [0|1] "" EON
SG_ SEATBELT_DRIVER_LATCHED : 13|1@0+ (1,0) [0|1] "" EON
SG_ PASS_AIRBAG_OFF : 14|1@0+ (1,0) [0|1] "" EON
SG_ PASS_AIRBAG_ON : 15|1@0+ (1,0) [0|1] "" EON
SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON
SG_ CHECKSUM : 51|4@0+ (1,0) [0|3] "" EON
BO_ 777 CAR_SPEED: 8 PCM
SG_ ROUGH_CAR_SPEED : 23|8@0+ (1,0) [0|255] "mph" XXX
SG_ CAR_SPEED : 7|16@0+ (0.01,0) [0|65535] "kph" XXX
SG_ ROUGH_CAR_SPEED_3 : 39|16@0+ (0.01,0) [0|65535] "kph" XXX
SG_ ROUGH_CAR_SPEED_2 : 31|8@0+ (1,0) [0|255] "mph" XXX
SG_ LOCK_STATUS : 55|2@0+ (1,0) [0|255] "" XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX
SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX
BO_ 780 ACC_HUD: 8 ADAS
SG_ CRUISE_SPEED : 31|8@0+ (1,0) [0|255] "kph" BDY
SG_ DTC_MODE : 39|1@0+ (1,0) [0|1] "" BDY
SG_ BOH : 38|1@0+ (1,0) [0|1] "" BDY
SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY
SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY
SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY
SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY
SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY
SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY
SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY
SG_ ZEROS_BOH : 7|24@0+ (0.002759506,0) [0|100] "m/s" BDY
SG_ FCM_OFF : 35|1@0+ (1,0) [0|1] "" BDY
SG_ SET_TO_1 : 36|1@0+ (1,0) [0|1] "" XXX
SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY
SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY
SG_ ACC_PROBLEM : 37|1@0+ (1,0) [0|1] "" BDY
SG_ ACC_ON : 52|1@0+ (1,0) [0|1] "" XXX
SG_ BOH_6 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ SET_TO_X1 : 55|1@0+ (1,0) [0|1] "" XXX
SG_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX
SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX
BO_ 804 CRUISE: 8 PCM
SG_ TRIP_FUEL_CONSUMED : 23|16@0+ (1,0) [0|255] "" EON
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON
SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON
BO_ 806 SCM_FEEDBACK: 8 SCM
SG_ DRIVERS_DOOR_OPEN : 17|1@0+ (1,0) [0|1] "" XXX
SG_ MAIN_ON : 28|1@0+ (1,0) [0|1] "" EON
SG_ RIGHT_BLINKER : 27|1@0+ (1,0) [0|1] "" EON
SG_ LEFT_BLINKER : 26|1@0+ (1,0) [0|1] "" EON
SG_ CMBS_STATES : 22|2@0+ (1,0) [0|3] "" EON
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX
SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX
BO_ 829 LKAS_HUD: 5 ADAS
SG_ CAM_TEMP_HIGH : 7|1@0+ (1,0) [0|255] "" BDY
SG_ SET_ME_X41 : 6|7@0+ (1,0) [0|127] "" BDY
SG_ BOH : 6|7@0+ (1,0) [0|127] "" BDY
SG_ DASHED_LANES : 14|1@0+ (1,0) [0|1] "" BDY
SG_ DTC : 13|1@0+ (1,0) [0|1] "" BDY
SG_ LKAS_PROBLEM : 12|1@0+ (1,0) [0|1] "" BDY
SG_ LKAS_OFF : 11|1@0+ (1,0) [0|1] "" BDY
SG_ SOLID_LANES : 10|1@0+ (1,0) [0|1] "" BDY
SG_ LDW_RIGHT : 9|1@0+ (1,0) [0|1] "" BDY
SG_ STEERING_REQUIRED : 8|1@0+ (1,0) [0|1] "" BDY
SG_ BOH : 23|2@0+ (1,0) [0|4] "" BDY
SG_ LDW_PROBLEM : 21|1@0+ (1,0) [0|1] "" BDY
SG_ BEEP : 17|2@0+ (1,0) [0|1] "" BDY
SG_ LDW_ON : 28|1@0+ (1,0) [0|1] "" BDY
SG_ LDW_OFF : 27|1@0+ (1,0) [0|1] "" BDY
SG_ CLEAN_WINDSHIELD : 26|1@0+ (1,0) [0|1] "" BDY
SG_ SET_ME_X48 : 31|8@0+ (1,0) [0|255] "" BDY
SG_ COUNTER : 37|2@0+ (1,0) [0|3] "" BDY
SG_ CHECKSUM : 35|4@0+ (1,0) [0|15] "" BDY
BO_ 862 CAMERA_MESSAGES: 8 CAM
SG_ ZEROS_BOH : 7|50@0+ (1,0) [0|127] "" BDY
SG_ AUTO_HIGHBEAMS_ACTIVE : 53|1@0+ (1,0) [0|1] "" XXX
SG_ HIGHBEAMS_ON : 52|1@0+ (1,0) [0|1] "" XXX
SG_ ZEROS_BOH_2 : 51|4@0+ (1,0) [0|15] "" XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX
SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX
BO_ 884 STALK_STATUS: 8 XXX
SG_ AUTO_HEADLIGHTS : 46|1@0+ (1,0) [0|1] "" EON
SG_ HIGH_BEAM_HOLD : 47|1@0+ (1,0) [0|1] "" EON
SG_ HIGH_BEAM_FLASH : 45|1@0+ (1,0) [0|1] "" EON
SG_ HEADLIGHTS_ON : 54|1@0+ (1,0) [0|1] "" EON
SG_ WIPER_SWITCH : 53|2@0+ (1,0) [0|3] "" XXX
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON
BO_ 891 STALK_STATUS_2: 8 XXX
SG_ WIPERS : 17|2@0+ (1,0) [0|3] "" EON
SG_ LOW_BEAMS : 35|1@0+ (1,0) [0|1] "" XXX
SG_ HIGH_BEAMS : 34|1@0+ (1,0) [0|1] "" XXX
SG_ PARK_LIGHTS : 36|1@0+ (1,0) [0|1] "" XXX
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON
CM_ SG_ 479 AEB_STATUS "set for the duration of AEB event";
CM_ SG_ 479 AEB_BRAKING "set when braking is commanded during AEB event";
CM_ SG_ 479 AEB_PREPARE "set 1s before AEB";
CM_ SG_ 576 LINE_DISTANCE_VISIBLE "Length of line visible, undecoded";
CM_ SG_ 577 LINE_FAR_EDGE_POSITION "Appears to be a measure of line thickness, indicates location of the portion of the line furthest from the car, undecoded";
CM_ SG_ 577 LINE_PARAMETER "Unclear if this is low quality line curvature rate or if this is something else, but it is correlated with line curvature, undecoded";
CM_ SG_ 577 LINE_DASHED "1 = line is dashed";
CM_ SG_ 577 LINE_SOLID "1 = line is solid";
VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ;
CM_ "acura_rdx_2020_can.dbc starts here"
BO_ 304 GAS_PEDAL_2: 8 PCM
SG_ ENGINE_TORQUE_ESTIMATE : 7|16@0- (1,0) [-1000|1000] "Nm" EON
SG_ ENGINE_TORQUE_REQUEST : 23|16@0- (1,0) [-1000|1000] "Nm" EON
SG_ CAR_GAS : 39|8@0+ (1,0) [0|255] "" EON
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON
SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON
BO_ 419 GEARBOX: 8 PCM
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON
SG_ GEAR_SHIFTER : 29|6@0+ (1,0) [0|63] "" EON
SG_ GEAR : 7|8@0+ (1,0) [0|255] "" EON
BO_ 432 STANDSTILL: 7 VSA
SG_ BRAKE_ERROR_1 : 11|1@0+ (1,0) [0|1] "" EON
SG_ BRAKE_ERROR_2 : 9|1@0+ (1,0) [0|1] "" EON
SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON
SG_ CHECKSUM : 51|4@0+ (1,0) [0|15] "" EON
BO_ 446 BRAKE_MODULE: 3 VSA
SG_ BRAKE_PRESSED : 4|1@0+ (1,0) [0|1] "" XXX
SG_ COUNTER : 21|2@0+ (1,0) [0|3] "" XXX
SG_ CHECKSUM : 19|4@0+ (1,0) [0|15] "" XXX
BO_ 927 RADAR_HUD: 8 RADAR
SG_ ZEROS_BOH : 7|10@0+ (1,0) [0|127] "" BDY
SG_ CMBS_OFF : 12|1@0+ (1,0) [0|1] "" BDY
SG_ RESUME_INSTRUCTION : 21|1@0+ (1,0) [0|1] "" XXX
SG_ SET_TO_1 : 13|1@0+ (1,0) [0|1] "" BDY
SG_ ZEROS_BOH2 : 11|4@0+ (1,0) [0|1] "" XXX
SG_ APPLY_BRAKES_FOR_CANC : 23|1@0+ (1,0) [0|1] "" XXX
SG_ ACC_ALERTS : 20|5@0+ (1,0) [0|1] "" BDY
SG_ SET_TO_0 : 22|1@0+ (1,0) [0|1] "" XXX
SG_ LEAD_DISTANCE : 39|8@0+ (1,0) [0|255] "" XXX
SG_ BOH : 40|1@0+ (1,0) [0|1] "" XXX
SG_ BOH_2 : 30|1@0+ (1,0) [0|1] "" XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX
SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX
BO_ 1302 ODOMETER: 8 XXX
SG_ ODOMETER : 7|24@0+ (1,0) [0|16777215] "km" EON
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON
VAL_ 419 GEAR_SHIFTER 32 "D" 8 "R" 4 "P" ;
VAL_ 545 ECON_ON_2 0 "off" 3 "on" ;
VAL_ 662 CRUISE_BUTTONS 7 "tbd" 6 "tbd" 5 "tbd" 4 "accel_res" 3 "decel_set" 2 "cancel" 1 "main" 0 "none" ;
VAL_ 662 CRUISE_SETTING 3 "distance_adj" 2 "tbd" 1 "lkas_button" 0 "none" ;
VAL_ 806 CMBS_BUTTON 3 "pressed" 0 "released" ;
VAL_ 891 WIPERS 4 "High" 2 "Low" 0 "Off" ;
VAL_ 829 BEEP 3 "single_beep" 2 "triple_beep" 1 "repeated_beep" 0 "no_beep" ;
CM_ "CHFFR_METRIC 330 STEER_ANGLE STEER_ANGLE 0.36 180; CHFFR_METRIC 380 ENGINE_RPM ENGINE_RPM 1 0; CHFFR_METRIC 804 ENGINE_TEMPERATURE ENGINE_TEMPERATURE 1 0";

View File

@ -34,7 +34,7 @@ class BuildExtWithoutPlatformSuffix(build_ext):
return get_ext_filename_without_platform_suffix(filename)
extra_compile_args = ["-std=c++14", "-Wno-nullability-completeness"]
extra_compile_args = ["-std=c++1z", "-Wno-nullability-completeness"]
ARCH = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip() # pylint: disable=unexpected-keyword-arg
if ARCH == "aarch64":
extra_compile_args += ["-Wno-deprecated-register"]

View File

@ -388,7 +388,7 @@ BO_ 304 GAS_PEDAL_2: 8 PCM
SG_ CAR_GAS : 39|8@0+ (1,0) [0|255] "" EON
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON
SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON
BO_ 401 GEARBOX: 8 PCM
SG_ GEAR_SHIFTER : 5|6@0+ (1,0) [0|63] "" EON
SG_ BOH : 45|6@0+ (1,0) [0|63] "" XXX
@ -405,6 +405,11 @@ BO_ 432 STANDSTILL: 7 VSA
SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON
SG_ CHECKSUM : 51|4@0+ (1,0) [0|15] "" EON
BO_ 506 LEGACY_BRAKE_COMMAND: 8 ADAS
SG_ CHIME : 40|8@1+ (1,0) [0|255] "" XXX
SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX
BO_ 892 CRUISE_PARAMS: 8 PCM
SG_ CRUISE_SPEED_OFFSET : 31|8@0- (0.1,0) [-128|127] "kph" EON
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON

View File

@ -400,6 +400,11 @@ BO_ 432 STANDSTILL: 7 VSA
SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON
SG_ CHECKSUM : 51|4@0+ (1,0) [0|15] "" EON
BO_ 506 LEGACY_BRAKE_COMMAND: 8 ADAS
SG_ CHIME : 40|8@1+ (1,0) [0|255] "" XXX
SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX
BO_ 892 CRUISE_PARAMS: 8 PCM
SG_ CRUISE_SPEED_OFFSET : 31|8@0- (0.1,0) [-128|127] "kph" EON
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON

View File

@ -424,6 +424,14 @@ BO_ 956 GEAR_PACKET: 8 XXX
SG_ GEAR : 13|6@0+ (1,0) [0|63] "" XXX
SG_ ECON_ON : 40|1@0+ (1,0) [0|1] "" XXX
BO_ 1653 Date_Time: 8 XXX
SG_ Year : 23|8@0+ (1,0) [0|255] "" XXX
SG_ Month : 31|8@0+ (1,0) [0|255] "" XXX
SG_ Day : 39|8@0+ (1,0) [0|255] "" XXX
SG_ Hour : 47|8@0+ (1,0) [0|255] "" XXX
SG_ Minute : 55|8@0+ (1,0) [0|255] "" XXX
SG_ Second : 63|8@0+ (1,0) [0|255] "" XXX
CM_ SG_ 548 BRAKE_PRESSURE "seems prop to pedal force";
CM_ SG_ 548 BRAKE_POSITION "seems proportional to pedal displacement, unclear the max value of 0x1c8";
CM_ SG_ 610 TYPE "seems 1 on Corolla, 0 on all others";

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,6 +1,6 @@
//=============================================================================
//
// Copyright (c) 2015 Qualcomm Technologies, Inc.
// Copyright (c) 2015, 2020 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
//
@ -8,14 +8,11 @@
#ifndef __IDIAGLOG_HPP_
#define __IDIAGLOG_HPP_
#ifndef ZDL_LOGGING_EXPORT
#define ZDL_LOGGING_EXPORT __attribute__((visibility("default")))
#endif
#include <string>
#include "DiagLog/Options.hpp"
#include "DlSystem/String.hpp"
#include "DlSystem/ZdlExportDefine.hpp"
namespace zdl
{
@ -26,10 +23,10 @@ namespace DiagLog
@{ */
/// @brief .
///
///
/// Interface for controlling logging for zdl components.
class ZDL_LOGGING_EXPORT IDiagLog
class ZDL_EXPORT IDiagLog
{
public:
@ -48,7 +45,7 @@ public:
///
/// @return Diag log options object.
virtual Options getOptions() = 0;
/// @brief .
///
/// Allows for setting the log mask once diag logging has started

View File

@ -1,6 +1,6 @@
//=============================================================================
//
// Copyright (c) 2015 Qualcomm Technologies, Inc.
// Copyright (c) 2015, 2020 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
//
@ -8,12 +8,8 @@
#ifndef __DIAGLOG_OPTIONS_HPP_
#define __DIAGLOG_OPTIONS_HPP_
#ifndef ZDL_LOGGING_EXPORT
#define ZDL_LOGGING_EXPORT __attribute__((visibility("default")))
#endif
#include <string>
#include <set>
#include "DlSystem/ZdlExportDefine.hpp"
namespace zdl
{
@ -25,7 +21,7 @@ namespace DiagLog
/// @brief .
///
/// Options for setting up diagnostic logging for zdl components.
class ZDL_LOGGING_EXPORT Options
class ZDL_EXPORT Options
{
public:
Options() :
@ -40,12 +36,12 @@ public:
}
/// @brief .
///
///
/// Enables diag logging only on the specified area mask (DNN_RUNTIME=ON | OFF)
std::string DiagLogMask;
/// @brief .
///
///
/// The path to the directory where log files will be written.
/// The path may be relative or absolute. Relative paths are interpreted
/// from the current working directory.
@ -53,15 +49,15 @@ public:
std::string LogFileDirectory;
/// @brief .
///
///
//// The name used for log files. If this value is empty then BaseName will be
/// used as the default file name.
/// Default value is "DiagLog"
std::string LogFileName;
/// @brief .
///
/// The maximum number of log files to create. If set to 0 no log rotation
///
/// The maximum number of log files to create. If set to 0 no log rotation
/// will be used and the log file name specified will be used each time, overwriting
/// any existing log file that may exist.
/// Default value is 20

View File

@ -1,6 +1,6 @@
//=============================================================================
//
// Copyright (c) 2015,2019 Qualcomm Technologies, Inc.
// Copyright (c) 2015-2020 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
//
@ -14,7 +14,6 @@
#include <string>
#include <vector>
#include <set>
#include <stdexcept>
#include "DlSystem/ZdlExportDefine.hpp"
#include "DlSystem/String.hpp"
@ -76,7 +75,7 @@ public:
*
* @return A pointer to the initialized container
*/
ZDL_EXPORT static std::unique_ptr<IDlContainer>
static std::unique_ptr<IDlContainer>
open(const std::string &filename) noexcept;
/**
@ -86,7 +85,7 @@ public:
*
* @return A pointer to the initialized container
*/
ZDL_EXPORT static std::unique_ptr<IDlContainer>
static std::unique_ptr<IDlContainer>
open(const zdl::DlSystem::String &filename) noexcept;
/**
@ -97,7 +96,7 @@ public:
*
* @return A pointer to the initialized container
*/
ZDL_EXPORT static std::unique_ptr<IDlContainer>
static std::unique_ptr<IDlContainer>
open(const std::vector<uint8_t> &buffer) noexcept;
/**
@ -110,7 +109,7 @@ public:
*
* @return A pointer to the initialized container
*/
ZDL_EXPORT static std::unique_ptr<IDlContainer>
static std::unique_ptr<IDlContainer>
open(const uint8_t* buffer, const size_t size) noexcept;

View File

@ -1,6 +1,6 @@
//==============================================================================
//
// Copyright (c) 2014-2019 Qualcomm Technologies, Inc.
// Copyright (c) 2014-2020 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
//
@ -128,9 +128,13 @@ enum class ProfilingLevel_t
BASIC = 1,
/// Detailed profiling
/// Collects more runtime stats in the DiagLog
/// Collects more runtime stats in the DiagLog, including per-layer statistics
/// Performance may be impacted
DETAILED = 2
DETAILED = 2,
/// Moderate profiling
/// Collects more runtime stats in the DiagLog, no per-layer statistics
MODERATE = 3
};
/**

View File

@ -1,6 +1,6 @@
//==============================================================================
//
// Copyright (c) 2016-2019 Qualcomm Technologies, Inc.
// Copyright (c) 2016-2020 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
//
@ -79,6 +79,7 @@ enum class ZDL_EXPORT ErrorCode : uint32_t {
SNPE_DLCONTAINER_BAD_DNN_FORMAT_VERSION = 312,
SNPE_DLCONTAINER_UNKNOWN_AXIS_ANNOTATION = 313,
SNPE_DLCONTAINER_UNKNOWN_SHUFFLE_TYPE = 314,
SNPE_DLCONTAINER_TEMP_FILE_FAILURE = 315,
// Network errors
SNPE_NETWORK_EMPTY_NETWORK = 400,
@ -191,7 +192,11 @@ enum class ZDL_EXPORT ErrorCode : uint32_t {
// DlCaching errors
SNPE_DLCACHING_INVALID_METADATA = 1500,
SNPE_DLCACHING_INVALID_INITBLOB = 1501
SNPE_DLCACHING_INVALID_INITBLOB = 1501,
// Infrastructure Errors
SNPE_INFRA_CLUSTERMGR_INSTANCE_INVALID = 1600,
SNPE_INFRA_CLUSTERMGR_EXECUTE_SYNC_FAILED = 1601
};

View File

@ -1,6 +1,6 @@
//==============================================================================
//
// Copyright (c) 2016 Qualcomm Technologies, Inc.
// Copyright (c) 2016, 2020 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
//
@ -11,6 +11,7 @@
#include <cstdio>
#include <utility>
#include <stdexcept>
#include "DlSystem/ZdlExportDefine.hpp"
@ -173,25 +174,25 @@ private:
template <typename Q = T>
typename std::enable_if<std::is_same<U, Q>::value, const Q&>::type GetReference() const noexcept {
if (!isReference()) throw std::bad_exception();
if (!isReference()) std::terminate();
return *static_cast<const Q*>(m_StoragePtr);
}
template <typename Q = T>
typename std::enable_if<std::is_same<U*, Q>::value, const Q&>::type GetReference() const noexcept {
if (!isPointer()) throw std::bad_exception();
if (!isPointer()) std::terminate();
return static_cast<const Q&>(m_StoragePtr);
}
template <typename Q = T>
typename std::enable_if<std::is_same<U, Q>::value, Q&>::type GetReference() noexcept {
if (!isReference()) throw std::bad_exception();
if (!isReference()) std::terminate();
return *m_StoragePtr;
}
template <typename Q = T>
typename std::enable_if<std::is_same<U*, Q>::value, Q&>::type GetReference() noexcept {
if (!isPointer()) throw std::bad_exception();
if (!isPointer()) std::terminate();
return m_StoragePtr;
}

View File

@ -1,6 +1,6 @@
//=============================================================================
//
// Copyright (c) 2015-2018 Qualcomm Technologies, Inc.
// Copyright (c) 2015-2020 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
//
@ -14,7 +14,6 @@
#include "TensorShape.hpp"
#include "ZdlExportDefine.hpp"
#include <memory>
#include <vector>
#include <ostream>
#include <cmath>

View File

@ -1,6 +1,6 @@
//=============================================================================
//
// Copyright (c) 2015 Qualcomm Technologies, Inc.
// Copyright (c) 2015-2020 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
//
@ -13,7 +13,6 @@
#include <memory>
#include <iterator>
#include <vector>
namespace DlSystem
{

View File

@ -1,6 +1,6 @@
//==============================================================================
//
// Copyright (c) 2017-2019 Qualcomm Technologies, Inc.
// Copyright (c) 2017-2020 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
//
@ -160,6 +160,14 @@ public:
m_StepExactly0(stepFor0),
m_QuantizedStepSize(stepSize) {};
UserBufferEncodingTf8(const zdl::DlSystem::UserBufferEncoding &ubEncoding) : UserBufferEncodingUnsigned8Bit(ubEncoding.getElementType()){
const zdl::DlSystem::UserBufferEncodingTf8* ubEncodingTf8
= dynamic_cast <const zdl::DlSystem::UserBufferEncodingTf8*> (&ubEncoding);
if (ubEncodingTf8) {
m_StepExactly0 = ubEncodingTf8->getStepExactly0();
m_QuantizedStepSize = ubEncodingTf8->getQuantizedStepSize();
}
}
/**
* @brief Sets the step value that represents 0
@ -246,6 +254,17 @@ public:
bitWidth(bWidth),
m_StepExactly0(stepFor0),
m_QuantizedStepSize(stepSize){};
UserBufferEncodingTfN(const zdl::DlSystem::UserBufferEncoding &ubEncoding) : UserBufferEncoding(ubEncoding.getElementType()){
const zdl::DlSystem::UserBufferEncodingTfN* ubEncodingTfN
= dynamic_cast <const zdl::DlSystem::UserBufferEncodingTfN*> (&ubEncoding);
if (ubEncodingTfN) {
m_StepExactly0 = ubEncodingTfN->getStepExactly0();
m_QuantizedStepSize = ubEncodingTfN->getQuantizedStepSize();
bitWidth = ubEncodingTfN->bitWidth;
}
}
size_t getElementSize() const noexcept override;
/**
* @brief Sets the step value that represents 0
@ -283,7 +302,7 @@ public:
* @return Minimum representable floating point value
*/
float getMin() const {
return m_QuantizedStepSize * (0 - (double)m_StepExactly0);
return static_cast<float>(m_QuantizedStepSize * (0 - (double)m_StepExactly0));
}
/**
@ -293,7 +312,7 @@ public:
* @return Maximum representable floating point value
*/
float getMax() const{
return m_QuantizedStepSize * (pow(2,bitWidth)-1 - (double)m_StepExactly0);
return static_cast<float>(m_QuantizedStepSize * (pow(2,bitWidth)-1 - (double)m_StepExactly0));
};
/**

View File

@ -1,6 +1,6 @@
//=============================================================================
//
// Copyright (c) 2017 Qualcomm Technologies, Inc.
// Copyright (c) 2017, 2020 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
//
@ -12,10 +12,7 @@
#include <cstdio>
#include <string>
#include <ostream>
#ifndef ZDL_EXPORT
#define ZDL_EXPORT __attribute__((visibility("default")))
#endif
#include "DlSystem/ZdlExportDefine.hpp"
namespace zdl
{
@ -105,4 +102,3 @@ ZDL_EXPORT std::ostream& operator<<(std::ostream& os, const String& str) noexcep
/** @} */ /* end_addtogroup c_plus_plus_apis C++ */
#endif // PLATFORM_STANDARD_STRING_HPP

View File

@ -1,6 +1,6 @@
//=============================================================================
//
// Copyright (c) 2017 Qualcomm Technologies, Inc.
// Copyright (c) 2017-2020 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
//
@ -8,7 +8,6 @@
#include <initializer_list>
#include <cstdio>
#include <memory>
#include <vector>
#include "ZdlExportDefine.hpp"
#include "DlSystem/TensorShape.hpp"
#include "DlSystem/StringList.hpp"

View File

@ -1,16 +1,13 @@
//=============================================================================
//
// Copyright (c) 2015 Qualcomm Technologies, Inc.
// Copyright (c) 2015, 2020 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
//
//=============================================================================
#ifndef _ZDL_EXPORT_DEFINE_HPP_
#define _ZDL_EXPORT_DEFINE_HPP_
#pragma once
#ifndef ZDL_EXPORT
#define ZDL_EXPORT __attribute__((visibility("default")))
#endif
#define ZDL_EXPORT
#endif

View File

@ -0,0 +1,93 @@
// =============================================================================
//
// Copyright (c) 2018-2019 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
//
// =============================================================================
#ifndef SNPE_PLATFORMVALIDATOR_HPP
#define SNPE_PLATFORMVALIDATOR_HPP
#include "DlSystem/DlEnums.hpp"
#include "DlSystem/DlMacros.hpp"
SNPE_DISABLE_WARNINGS("-Wdelete-non-virtual-dtor","-Wdelete-non-virtual-dtor")
#include <string>
#include <memory>
SNPE_ENABLE_WARNINGS
namespace zdl
{
namespace SNPE
{
class PlatformValidator;
class IPlatformValidatorRuntime;
}
}
/** @addtogroup c_plus_plus_apis C++
@{ */
/**
* The class for checking SNPE compatibility/capability of a device.
*
*/
class zdl::SNPE::PlatformValidator
{
public:
/**
* @brief Default Constructor of the PlatformValidator Class
*
* @return A new instance of a PlatformValidator object
* that can be used to check the SNPE compatibility
* of a device
*/
PlatformValidator();
~PlatformValidator();
/**
* @brief Sets the runtime processor for compatibility check
*
* @return Void
*/
void setRuntime(zdl::DlSystem::Runtime_t runtime);
/**
* @brief Checks if the Runtime prerequisites for SNPE are available.
*
* @return True if the Runtime prerequisites are available, else false.
*/
bool isRuntimeAvailable();
/**
* @brief Returns the core version for the Runtime selected.
*
* @return String which contains the actual core version value
*/
std::string getCoreVersion();
/**
* @brief Returns the library version for the Runtime selected.
*
* @return String which contains the actual lib version value
*/
std::string getLibVersion();
/**
* @brief Runs a small program on the runtime and Checks if SNPE is supported for Runtime.
*
* @return If True, the device is ready for SNPE execution, else not.
*/
bool runtimeCheck();
private:
zdl::DlSystem::Runtime_t m_runtimeType;
std::unique_ptr<IPlatformValidatorRuntime> m_platformValidatorRuntime;
};
/** @} */ /* end_addtogroup c_plus_plus_apis C++ */
#endif //SNPE_PLATFORMVALIDATOR_HPP

View File

@ -1,6 +1,6 @@
// =============================================================================
//
// Copyright (c) 2019 Qualcomm Technologies, Inc.
// Copyright (c) 2019-2020 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
//
@ -10,7 +10,6 @@
#define PSNPE_HPP
#include <cstdlib>
#include <unordered_map>
#include <functional>
#include "SNPE/SNPE.hpp"
#include "DlSystem/UserBufferMap.hpp"
@ -73,22 +72,40 @@ struct ZDL_EXPORT InputOutputAsyncCallbackParam
};
};
/**
* @brief This callback is called when the output data is ready, only use for Output Async mode
*/
using OutputAsyncCallbackFunc = std::function<void(OutputAsyncCallbackParam)>;
/**
* @brief This callback is called when the output data is ready, only use for Output-Input Async mode
*/
using InputOutputAsyncCallbackFunc = std::function<void(InputOutputAsyncCallbackParam)>;
/**
* @brief This callback is called when the input data is ready,only use for Output-Input Async mode
*/
using InputOutputAsyncInputCallback = std::function<std::shared_ptr<ApplicationBufferMap>(const std::vector<std::string> &,
const zdl::DlSystem::StringList &)>;
/**
* @brief .
*
* A structure BulkSNPE configuration
* A structure PSNPE configuration
*
*/
struct ZDL_EXPORT BuildConfig final
{
BuildMode buildMode = BuildMode::SERIAL;
zdl::DlContainer::IDlContainer* container;
zdl::DlSystem::StringList outputBufferNames;
RuntimeConfigList runtimeConfigList;
OutputAsyncCallbackFunc outputCallback;
InputOutputAsyncCallbackFunc inputOutputCallback;
InputOutputTransmissionMode inputOutputTransmissionMode = InputOutputTransmissionMode::sync;
BuildMode buildMode = BuildMode::SERIAL; ///< Specify build in serial mode or parallel mode
zdl::DlContainer::IDlContainer* container;///< The opened container ptr
zdl::DlSystem::StringList outputBufferNames;///< Specify the output layer name
RuntimeConfigList runtimeConfigList;///< The runtime config list for PSNPE, @see RuntimeConfig
size_t inputThreadNumbers = 1;///< Specify the number of threads used in the execution phase to process input data, only used in inputOutputAsync mode
size_t outputThreadNumbers = 1;///< Specify the number of threads used in the execution phase to process output data, only used in inputOutputAsync and outputAsync mode
OutputAsyncCallbackFunc outputCallback;///< The callback to deal with output data ,only used in outputAsync mode
InputOutputAsyncCallbackFunc inputOutputCallback;///< The callback to deal with output data ,only used in inputOutputAsync mode
InputOutputAsyncInputCallback inputOutputInputCallback;///< The callback to deal with input data ,only used in inputOutputAsync mode
InputOutputTransmissionMode inputOutputTransmissionMode = InputOutputTransmissionMode::sync;///< Specify execution mode
zdl::DlSystem::ProfilingLevel_t profilingLevel = zdl::DlSystem::ProfilingLevel_t::OFF;///< Specify profiling level for Diaglog
uint64_t encode[2] = {0, 0};
bool enableInitCache = false;
};
/**
* @brief .
@ -130,7 +147,8 @@ class ZDL_EXPORT PSNPE final
*
* @return True if executed successfully; flase, otherwise.
*/
bool executeInputOutputAsync(const ApplicationBufferMap& inputMap, size_t dataIndex, bool isTF8buff) noexcept;
bool executeInputOutputAsync(const std::vector<std::string>& inputMap, size_t dataIndex, bool isTF8buff) noexcept;
bool executeInputOutputAsync(const std::vector<std::string>& inputMap, size_t dataIndex, bool isTF8buff,bool isTF8Outputbuff) noexcept;
/**
* @brief Returns the input layer names of the network.
*
@ -161,6 +179,8 @@ class ZDL_EXPORT PSNPE final
*/
const zdl::DlSystem::TensorShape getBufferAttributesDims(const char *name) const noexcept;
zdl::DlSystem::Optional<zdl::DlSystem::IBufferAttributes*> getInputOutputBufferAttributes(const char *name) const noexcept;
private:
PSNPE(const PSNPE&) = delete;
PSNPE& operator=(const PSNPE&) = delete;

View File

@ -1,6 +1,6 @@
//==============================================================================
//
// Copyright (c) 2019 Qualcomm Technologies, Inc.
// Copyright (c) 2019-2020 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
//
@ -9,80 +9,77 @@
#define PSNPE_RUNTIMECONFIGLIST_HPP
#include <iostream>
#include "DlSystem/DlEnums.hpp"
#include "DlContainer/IDlContainer.hpp"
#include "DlSystem/ZdlExportDefine.hpp"
#include "DlSystem/DlEnums.hpp"
#include "DlSystem/RuntimeList.hpp"
#include "DlSystem/TensorShapeMap.hpp"
#include "DlSystem/ZdlExportDefine.hpp"
namespace zdl {
namespace PSNPE
{
namespace PSNPE {
/** @addtogroup c_plus_plus_apis C++
@{ */
/**
* @brief .
*
* The structure for configuring a BulkSNPE runtime
*
*/
* @brief .
*
* The structure for configuring a BulkSNPE runtime
*
*/
struct ZDL_EXPORT RuntimeConfig final {
zdl::DlSystem::Runtime_t runtime;
zdl::DlSystem::RuntimeList runtimeList;
zdl::DlSystem::PerformanceProfile_t perfProfile;
bool enableCPUFallback;
RuntimeConfig(): runtime{zdl::DlSystem::Runtime_t::CPU_FLOAT32},
perfProfile{zdl::DlSystem::PerformanceProfile_t::HIGH_PERFORMANCE},
enableCPUFallback{false}
{}
RuntimeConfig(const RuntimeConfig& other)
{
runtime = other.runtime;
runtimeList = other.runtimeList;
perfProfile = other.perfProfile;
enableCPUFallback = other.enableCPUFallback;
}
zdl::DlSystem::Runtime_t runtime;
zdl::DlSystem::RuntimeList runtimeList;
zdl::DlSystem::PerformanceProfile_t perfProfile;
zdl::DlSystem::TensorShapeMap inputDimensionsMap;
bool enableCPUFallback;
RuntimeConfig()
: runtime{zdl::DlSystem::Runtime_t::CPU_FLOAT32},
perfProfile{zdl::DlSystem::PerformanceProfile_t::HIGH_PERFORMANCE},
enableCPUFallback{false} {}
RuntimeConfig(const RuntimeConfig& other) {
runtime = other.runtime;
runtimeList = other.runtimeList;
perfProfile = other.perfProfile;
enableCPUFallback = other.enableCPUFallback;
inputDimensionsMap = other.inputDimensionsMap;
}
RuntimeConfig& operator=(const RuntimeConfig &other)
{
this->runtimeList = other.runtimeList;
this->runtime = other.runtime;
this->perfProfile = other.perfProfile;
this->enableCPUFallback = other.enableCPUFallback;
return *this;
}
~RuntimeConfig() {}
RuntimeConfig& operator=(const RuntimeConfig& other) {
this->runtimeList = other.runtimeList;
this->runtime = other.runtime;
this->perfProfile = other.perfProfile;
this->enableCPUFallback = other.enableCPUFallback;
this->inputDimensionsMap = other.inputDimensionsMap;
return *this;
}
~RuntimeConfig() {}
};
/**
* @brief .
*
* The class for creating a RuntimeConfig container.
*
*/
class ZDL_EXPORT RuntimeConfigList final
{
public:
RuntimeConfigList();
RuntimeConfigList(const size_t size);
void push_back(const RuntimeConfig &runtimeConfig);
RuntimeConfig& operator[](const size_t index);
RuntimeConfigList& operator =(const RuntimeConfigList &other);
size_t size() const noexcept;
size_t capacity() const noexcept;
void clear() noexcept;
~RuntimeConfigList() = default;
private:
void swap(const RuntimeConfigList &other);
std::vector<RuntimeConfig> m_runtimeConfigs;
* @brief .
*
* The class for creating a RuntimeConfig container.
*
*/
class ZDL_EXPORT RuntimeConfigList final {
public:
RuntimeConfigList();
RuntimeConfigList(const size_t size);
void push_back(const RuntimeConfig& runtimeConfig);
RuntimeConfig& operator[](const size_t index);
RuntimeConfigList& operator=(const RuntimeConfigList& other);
size_t size() const noexcept;
size_t capacity() const noexcept;
void clear() noexcept;
~RuntimeConfigList() = default;
private:
void swap(const RuntimeConfigList& other);
std::vector<RuntimeConfig> m_runtimeConfigs;
};
/** @} */ /* end_addtogroup c_plus_plus_apis C++ */
} // namespace PSNPE
} // namespace zdl
#endif //PSNPE_RUNTIMECONFIGLIST_HPP
} // namespace PSNPE
} // namespace zdl
#endif // PSNPE_RUNTIMECONFIGLIST_HPP

View File

@ -1,6 +1,6 @@
//==============================================================================
//
// Copyright (c) 2015-2017 Qualcomm Technologies, Inc.
// Copyright (c) 2015-2020 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
//
@ -9,9 +9,6 @@
#ifndef _SNPE_SNPE_HPP_
#define _SNPE_SNPE_HPP_
#include <map>
#include <vector>
#include "DlSystem/DlOptional.hpp"
#include "DlSystem/DlVersion.hpp"
#include "DlSystem/IBufferAttributes.hpp"

View File

@ -0,0 +1,483 @@
//==============================================================================
//
// Copyright (c) 2019-2020 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
//
//==============================================================================
#ifndef SNPE_UDO_BASE_H
#define SNPE_UDO_BASE_H
#include <stdint.h>
// Provide values to use for API version.
#define API_VERSION_MAJOR 1
#define API_VERSION_MINOR 5
#define API_VERSION_TEENY 0
/** @addtogroup c_plus_plus_apis C++
@{ */
// Defines a bitmask of enum values.
typedef uint32_t SnpeUdo_Bitmask_t;
// A string of characters, rather than an array of bytes.
// Assumed to be UTF-8.
typedef char* SnpeUdo_String_t;
// The maximum allowable length of a SnpeUdo_String_t in bytes,
// including null terminator. SNPE will truncate strings longer
// than this.
#define SNPE_UDO_MAX_STRING_SIZE 1024
/**
* An enum which holds the various error types.
* The error types are divided to classes :
* 0 - 99 : generic errors
* 100 - 200 : errors related to configuration
*
*/
typedef enum
{
/// No Error
SNPE_UDO_NO_ERROR = 0,
/// Unsupported value for core type
SNPE_UDO_WRONG_CORE = 1,
/// Invalid attribute/argument passed into UDO API
SNPE_UDO_INVALID_ARGUMENT = 2,
/// Unsupported feature error
SNPE_UDO_UNSUPPORTED_FEATURE = 3,
/// Error relating to memory allocation
SNPE_UDO_MEM_ALLOC_ERROR = 4,
/* Configuration Specific errors */
/// No op with given attributes available in library
SNPE_UDO_WRONG_OPERATION = 100,
/// Unsupported value for core type in UDO configuration
SNPE_UDO_WRONG_CORE_TYPE = 101,
/// Wrong number of params in UDO definition
SNPE_UDO_WRONG_NUM_OF_PARAMS = 102,
/// Wrong number of dimensions for tensor(s) in UDO definition
SNPE_UDO_WRONG_NUM_OF_DIMENSIONS = 103,
/// Wrong number of input tensors in UDO definition
SNPE_UDO_WRONG_NUM_OF_INPUTS = 104,
/// Wrong number of output tensors in UDO definition
SNPE_UDO_WRONG_NUM_OF_OUTPUTS = 105,
SNPE_UDO_PROGRAM_CACHE_NOT_FOUND = 106,
SNPE_UDO_UNKNOWN_ERROR = 0xFFFFFFFF
} SnpeUdo_ErrorType_t;
/**
* An enum which holds the various data types.
* Designed to be used as single values or combined into a bitfield parameter
* (0x1, 0x2, 0x4, etc)
* \n FIXED_XX types are targeted for data in tensors.
* \n UINT / INT types are targeted for scalar params
*/
typedef enum
{
/// data type: 16-bit floating point
SNPE_UDO_DATATYPE_FLOAT_16 = 0x01,
/// data type: 32-bit floating point
SNPE_UDO_DATATYPE_FLOAT_32 = 0x02,
/// data type: 4-bit fixed point
SNPE_UDO_DATATYPE_FIXED_4 = 0x04,
/// data type: 8-bit fixed point
SNPE_UDO_DATATYPE_FIXED_8 = 0x08,
/// data type: 16-bit fixed point
SNPE_UDO_DATATYPE_FIXED_16 = 0x10,
/// data type: 32-bit fixed point
SNPE_UDO_DATATYPE_FIXED_32 = 0x20,
/// data type: 8-bit unsigned integer
SNPE_UDO_DATATYPE_UINT_8 = 0x100,
/// data type: 16-bit unsigned integer
SNPE_UDO_DATATYPE_UINT_16 = 0x200,
/// data type: 32-bit unsigned integer
SNPE_UDO_DATATYPE_UINT_32 = 0x400,
/// data type: 8-bit signed integer
SNPE_UDO_DATATYPE_INT_8 = 0x1000,
/// data type: 16-bit signed integer
SNPE_UDO_DATATYPE_INT_16 = 0x2000,
/// data type: 32-bit signed integer
SNPE_UDO_DATATYPE_INT_32 = 0x4000,
SNPE_UDO_DATATYPE_LAST = 0xFFFFFFFF
} SnpeUdo_DataType_t;
/**
* An enum which holds the various layouts.
* Designed to be used as single values or combined into a bitfield parameter
* (0x1, 0x2, 0x4, etc)
*/
typedef enum
{
/// data layout (4D): NHWC (batch-height-width-channel)
SNPE_UDO_LAYOUT_NHWC = 0x01,
/// data layout (4D): NCHW (batch-channel-height-width)
SNPE_UDO_LAYOUT_NCHW = 0x02,
/// data layout (5D): NDHWC (batch-dimension-height-width-channel)
SNPE_UDO_LAYOUT_NDHWC = 0x04,
SNPE_UDO_LAYOUT_GPU_OPTIMAL1 = 0x08,
SNPE_UDO_LAYOUT_GPU_OPTIMAL2 = 0x10,
SNPE_UDO_LAYOUT_DSP_OPTIMAL1 = 0x11,
SNPE_UDO_LAYOUT_DSP_OPTIMAL2 = 0x12,
// Indicates no data will be allocated for this tensor.
// Used to specify optional inputs/outputs positionally.
SNPE_UDO_LAYOUT_NULL = 0x13,
SNPE_UDO_LAYOUT_LAST = 0xFFFFFFFF
} SnpeUdo_TensorLayout_t;
/**
* An enum which holds the UDO library Core type .
* Designed to be used as single values or combined into a bitfield parameter
* (0x1, 0x2, 0x4, etc)
*/
typedef enum
{
/// Library target IP Core is undefined
SNPE_UDO_CORETYPE_UNDEFINED = 0x00,
/// Library target IP Core is CPU
SNPE_UDO_CORETYPE_CPU = 0x01,
/// Library target IP Core is GPU
SNPE_UDO_CORETYPE_GPU = 0x02,
/// Library target IP Core is DSP
SNPE_UDO_CORETYPE_DSP = 0x04,
SNPE_UDO_CORETYPE_LAST = 0xFFFFFFFF
} SnpeUdo_CoreType_t;
/**
* An enum to specify the parameter type : Scalar or Tensor
*/
typedef enum
{
/// UDO static param type: scalar
SNPE_UDO_PARAMTYPE_SCALAR,
/// UDO static param type: string
SNPE_UDO_PARAMTYPE_STRING,
/// UDO static param type: tensor
SNPE_UDO_PARAMTYPE_TENSOR,
SNPE_UDO_PARAMTYPE_LAST = 0xFFFFFFFF
} SnpeUdo_ParamType_t;
/**
* An enum to specify quantization type
*/
typedef enum
{
/// Tensor Quantization type: NONE. Signifies unquantized tensor data
SNPE_UDO_QUANTIZATION_NONE,
/// Tensor Quantization type: Tensorflow-style
SNPE_UDO_QUANTIZATION_TF,
SNPE_UDO_QUANTIZATION_QMN,
SNPE_UDO_QUANTIZATION_LAST = 0xFFFFFFFF
} SnpeUdo_QuantizationType_t;
/**
* @brief A struct which is used to provide a version number using 3 values : major, minor, teeny
*
*/
typedef struct
{
/// version field: major - for backward-incompatible changes
uint32_t major;
/// version field: minor - for backward-compatible feature updates
uint32_t minor;
/// version field: teeny - for minor bug-fixes and clean-up
uint32_t teeny;
} SnpeUdo_Version_t;
/**
* @brief A struct returned from version query, contains the Library version and API version
*
*/
typedef struct
{
/// Version of UDO library. Controlled by users
SnpeUdo_Version_t libVersion;
/// Version of SNPE UDO API used in compiling library. Determined by SNPE
SnpeUdo_Version_t apiVersion;
} SnpeUdo_LibVersion_t;
/**
* @brief A union to hold the value of a generic type. Allows defining a parameter struct
* in a generic way, with a "value" location that holds the data regardless of the type.
*
*/
typedef union
{
/// value type: float
float floatValue;
/// value type: unsigned 32-bit integer
uint32_t uint32Value;
/// value type: signed 32-bit integer
int32_t int32Value;
/// value type: unsigned 16-bit integer
uint16_t uint16Value;
/// value type: signed 16-bit integer
int16_t int16Value;
/// value type: unsigned 8-bit integer
uint8_t uint8Value;
/// value type: signed 8-bit integer
int8_t int8Value;
} SnpeUdo_Value_t;
/**
* @brief A struct which defines a scalar parameter : name, data type, and union of values
*
*/
typedef struct
{
/// The parameter data type : float, int, etc.
SnpeUdo_DataType_t dataType;
/// a union of specified type which holds the data
SnpeUdo_Value_t dataValue;
} SnpeUdo_ScalarParam_t;
/**
* @brief A struct which defines the quantization parameters in case of Tensorflow style quantization
*
*/
typedef struct
{
/// minimum value of the quantization range of data
float minValue;
/// maximum value of the quantization range of data
float maxValue;
} SnpeUdo_TFQuantize_t;
/**
* @brief A struct which defines the quantization type, and union of supported quantization structs
*
*/
typedef struct
{
/// quantization type (only TF-style currently supported)
SnpeUdo_QuantizationType_t quantizeType;
union
{
/// TF-style min-max quantization ranges
SnpeUdo_TFQuantize_t TFParams;
};
} SnpeUdo_QuantizeParams_t;
/**
* @brief A struct which defines the datatype associated with a specified core-type
* This should be used to denote the datatypes for a single tensor info, depending
* on the intended execution core.
*
*/
typedef struct
{
/// The IP Core
SnpeUdo_CoreType_t coreType;
/// The associated datatype for this coreType
SnpeUdo_DataType_t dataType;
} SnpeUdo_PerCoreDatatype_t;
/**
* @brief A struct which defines a tensor parameter : name, data type, layout, quantization, more.
* Also holds a pointer to the tensor data.
*
*/
typedef struct
{
/// The maximum allowable dimensions of the tensor. The memory held in
/// _tensorData_ is guaranteed to be large enough for this.
uint32_t* maxDimensions;
/// The current dimensions of the tensor. An operation may modify the current
/// dimensions of its output, to indicate cases where the output has been
/// "resized".
/// Note that for static parameters, the current and max dimensions must
/// match.
uint32_t* currDimensions;
/// Quantization params applicable to the tensor. Currently only supports
/// Tensorflow quantization style.
SnpeUdo_QuantizeParams_t quantizeParams;
/// Number of dimensions to the tensor: 3D, 4D, etc.
uint32_t tensorRank;
/// The parameter data type: float, int, etc.
SnpeUdo_DataType_t dataType;
/// The tensor layout type: NCHW, NHWC, etc.
SnpeUdo_TensorLayout_t layout;
/// Opaque pointer to tensor data. User may be required to re-interpret the pointer
/// based on core-specific definitions.
void* tensorData;
} SnpeUdo_TensorParam_t;
/**
* @brief A struct which defines tensor information for activation tensors only
*
* It describes an activation tensor object using its name, the intended layout and the datatype
* it will take depending on the intended runtime core. The repeated field indicates that
* that the tensor info describes several input/output activation tensors, which all share the
* aforementioned properties.
*/
typedef struct
{
/// The tensor name
SnpeUdo_String_t tensorName;
/// The tensor layout type: NCHW, NHWC, etc.
SnpeUdo_TensorLayout_t layout;
/// The per core datatype: {SNPE_UDO_DATATYPE, SNPE_UDO_CORE_TYPE}
SnpeUdo_PerCoreDatatype_t* perCoreDatatype;
/// A boolean field indicating that this tensorinfo will be repeated e.x for ops such as Concat or Split
bool repeated;
} SnpeUdo_TensorInfo_t;
/**
* @brief struct which defines a UDO parameter - a union of scalar, tensor and string parameters
*
*/
typedef struct
{
/// Type is scalar or tensor
SnpeUdo_ParamType_t paramType;
/// The param name, for example : "offset", "activation_type"
SnpeUdo_String_t paramName;
union
{
/// scalar param value
SnpeUdo_ScalarParam_t scalarParam;
/// tensor param value
SnpeUdo_TensorParam_t tensorParam;
/// string param value
SnpeUdo_String_t stringParam;
};
} SnpeUdo_Param_t;
/**
* @brief A struct which defines Operation information which is specific for IP core (CPU, GPU, DSP ...)
*
*/
typedef struct
{
/// The IP Core
SnpeUdo_CoreType_t udoCoreType;
/// Bitmask, defines supported internal calculation types (like FLOAT_32, etc)
/// Based on SnpeUdo_DataType
SnpeUdo_Bitmask_t operationCalculationTypes;
} SnpeUdo_OpCoreInfo_t;
/**
* @brief A struct which defines the common and core-specific Operation information
*
*/
typedef struct
{
/// Operation type
SnpeUdo_String_t operationType;
/// A bitmask describing which IP Cores (CPU, GPU, DSP ...) support this operation
/// Translated based on SnpeUdo_CoreType
SnpeUdo_Bitmask_t supportedByCores;
/// Number of static parameters defined by the op
uint32_t numOfStaticParams;
/// Array of static parameters. Can be scalar or tensor params
SnpeUdo_Param_t* staticParams;
/// Number of input tensors this op receives
uint32_t numOfInputs;
/// Array of input tensor names to this operation
SnpeUdo_String_t* inputNames;
/// Number of output tensors this op receives
uint32_t numOfOutputs;
/// Array of output tensor names to this operation
SnpeUdo_String_t* outputNames;
/// Number of cores that the op can execute on
uint32_t numOfCoreInfo;
/// Array of per-core information entries
SnpeUdo_OpCoreInfo_t* opPerCoreInfo;
/// Array of input tensor infos for this operation
SnpeUdo_TensorInfo_t* inputInfos;
/// Array of output tensor infos for this operation
SnpeUdo_TensorInfo_t* outputInfos;
} SnpeUdo_OperationInfo_t;
/**
* @brief A struct which provides the implementation library info : type, name
*
*/
typedef struct
{
/// Defines the IP Core that this implementation library is targeting
SnpeUdo_CoreType_t udoCoreType;
/// library name. will be looked at in the standard library path
SnpeUdo_String_t libraryName;
} SnpeUdo_LibraryInfo_t;
/**
* @brief A struct returned by the registration library and contains information on the UDO package :
* name, operations, libraries, etc.
*
*/
typedef struct
{
/// A string containing the package name
SnpeUdo_String_t packageName;
/// A bitmask describing supported IP cores (CPU, GPU, DSP ...)
/// Translated based on SnpeUdo_CoreType
SnpeUdo_Bitmask_t supportedCoreTypes;
/// The number of implementation libraries in the package
uint32_t numOfImplementationLib;
/// Array of implementation libraries names/types
SnpeUdo_LibraryInfo_t* implementationLib;
/// A string containing all operation types separated by space
SnpeUdo_String_t operationsString;
/// Number of supported operations
uint32_t numOfOperations;
/// Array of Operation info structs. Each entry describes one
/// Operation (name, params, inputs, outputs)
SnpeUdo_OperationInfo_t* operationsInfo;
} SnpeUdo_RegInfo_t;
/**
* @brief A struct returned by the implementation library and contains information on the
* specific library: name, IP Core, operations, etc.
*
*/
typedef struct
{
/// Defines the IP Core that this implementation library is targeting
SnpeUdo_CoreType_t udoCoreType;
/// A string containing the package name
SnpeUdo_String_t packageName;
/// A string containing all operation types separated by space
SnpeUdo_String_t operationsString;
/// Number of supported operations
uint32_t numOfOperations;
} SnpeUdo_ImpInfo_t;
/**
* @brief This struct defines an operation. It is used for validation
* or creation of an operation.
* In case of using it for creation, the static params which are tensors
* contain pointers to the real data (weights, for example), and input/output
* tensors also include pointers to the buffers used.
*/
typedef struct
{
/// The IP Core that the operation is defined for - CPU, GPU, DSP...
SnpeUdo_CoreType_t udoCoreType;
/// Operation type
SnpeUdo_String_t operationType;
/// The number of static parameters provided in the staticParams array.
/// this number has to match the number provided by the UDO Registration library information
uint32_t numOfStaticParams;
/// Array of static parameters
SnpeUdo_Param_t* staticParams;
/// The number of input parameters provided in inputs array.
/// this number has to match the number provided by the UDO Registration library information
uint32_t numOfInputs;
/// Array of input tensors, providing layout, data type, sizes, etc
/// When used to create an operation, also contains the initial location of the data
SnpeUdo_TensorParam_t* inputs;
/// The number of output parameters provided in inputs array.
/// this number has to match the number provided by the UDO Registration library information
uint32_t numOfOutputs;
/// Array of output tensors, providing layout, data type, sizes, etc
/// When used to create an operation, also contains the initial location of the data
SnpeUdo_TensorParam_t* outputs;
} SnpeUdo_OpDefinition_t;
/** @} */ /* end_addtogroup c_plus_plus_apis C++ */
#endif //SNPE_UDO_BASE_H

View File

@ -0,0 +1,323 @@
//==============================================================================
//
// Copyright (c) 2019-2020 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
//
//==============================================================================
#ifndef SNPE_UDO_IMPL_H
#define SNPE_UDO_IMPL_H
#include <stdbool.h>
#include "SnpeUdo/UdoShared.h"
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup c_plus_plus_apis C++
@{ */
typedef struct _SnpeUdo_OpFactory_t* SnpeUdo_OpFactory_t;
typedef struct _SnpeUdo_Operation_t* SnpeUdo_Operation_t;
/**
* @brief Initialize the shared library's data structures. Calling any other
* library function before this one will result in error.
*
* @param[in] globalInfrastructure Global core-specific infrastructure to be
* used by operations created in this library. The definition and
* semantics of this object will be defined in the corresponding
* implementation header for the core type.
* @return Error code
*/
SnpeUdo_ErrorType_t
SnpeUdo_initImplLibrary(void* globalInfrastructure);
typedef SnpeUdo_ErrorType_t
(*SnpeUdo_InitImplLibraryFunction_t)(void*);
/**
* @brief A function to query the API version of the UDO implementation library.
* The function populates a SnpeUdo_LibVersion_t struct, which contains a SnpeUdo_Version_t
* struct for API version and library version.
*
* @param[in, out] version A pointer to struct which contains major, minor, teeny information for
* library and api versions.
*
* @return Error code
*/
SnpeUdo_ErrorType_t
SnpeUdo_getImplVersion(SnpeUdo_LibVersion_t** version);
typedef SnpeUdo_ErrorType_t
(*SnpeUdo_getImplVersion_t)(SnpeUdo_LibVersion_t** version);
/**
* @brief Release the shared library's data structures, and invalidate any
* handles returned by the library. The behavior of any outstanding
* asynchronous calls made to this library when this function is called
* are undefined. All library functions (except SnpeUdo_initImplLibrary) will
* return an error after this function has been successfully called.
*
* It should be possible to call SnpeUdo_initImplLibrary after calling this
* function, and re-initialize the library.
*
* @return Error code
*/
SnpeUdo_ErrorType_t
SnpeUdo_terminateImplLibrary(void);
typedef SnpeUdo_ErrorType_t
(*SnpeUdo_TerminateImplLibraryFunction_t)(void);
/**
* @brief A function to query info on the UDO implementation library.
* The function populates a structure which contains information about
* operations that are part of this library
*
* @param[in, out] implementationInfo A pointer to struct which contains information
* on the operations
*
* @return error code
*
*/
SnpeUdo_ErrorType_t
SnpeUdo_getImpInfo(SnpeUdo_ImpInfo_t** implementationInfo);
typedef SnpeUdo_ErrorType_t
(*SnpeUdo_GetImpInfoFunction_t)(SnpeUdo_ImpInfo_t** implementationInfo);
/**
* @brief A function to create an operation factory.
* The function receives the operation type, and an array of static parameters,
* and returns operation factory handler
*
* @param[in] udoCoreType The Core type to create the operation on. An error will
* be returned if this does not match the core type of the library.
*
* @param[in] perFactoryInfrastructure CreateOpFactory infrastructure appropriate to this
* core type. The definition and semantics of this object will be defined
* in the corresponding implementation header for the core type.
*
* @param[in] operationType A string containing Operation type. for example "MY_CONV"
*
* @param[in] numOfStaticParams The number of static parameters.
*
* @param[in] staticParams Array of static parameters
*
* @param[in,out] opFactory Handler to Operation Factory, to be used when creating operations
*
* @return Error Code
*/
SnpeUdo_ErrorType_t
SnpeUdo_createOpFactory(SnpeUdo_CoreType_t udoCoreType,
void* perFactoryInfrastructure,
SnpeUdo_String_t operationType,
uint32_t numOfStaticParams,
SnpeUdo_Param_t* staticParams,
SnpeUdo_OpFactory_t* opFactory);
typedef SnpeUdo_ErrorType_t
(*SnpeUdo_CreateOpFactoryFunction_t)(SnpeUdo_CoreType_t,
void*,
SnpeUdo_String_t,
uint32_t,
SnpeUdo_Param_t*,
SnpeUdo_OpFactory_t*);
/**
* @brief A function to release the resources allocated for an operation factory
* created by this library.
*
* @param[in] factory The operation factory to release. Upon success this handle will be invalidated.
*
* @return Error Code
*/
SnpeUdo_ErrorType_t
SnpeUdo_releaseOpFactory(SnpeUdo_OpFactory_t opFactory);
typedef SnpeUdo_ErrorType_t
(*SnpeUdo_ReleaseOpFactoryFunction_t)(SnpeUdo_OpFactory_t);
/**
* @brief A function to create an operation from the factory.
* The function receives array of inputs and array of outputs, and creates an operation
* instance, returning the operation instance handler.
*
* @param[in] opFactory OpFactory instance containing the parameters for this operation.
*
* @param[in] perOpInfrastructure Per-Op infrastructure for this operation. The definition
* and semantics of this object will be defined in the implementation header
* appropriate to this core type.
*
* @param[in] numOfInputs The number of input tensors this operation will receive.
*
* @param[in] inputs Array of input tensors, providing both the sizes and initial
* location of the data.
*
* @param[in] numOfOutputs Number of output tensors this operation will produce.
*
* @param[in] outputs Array of output tensors, providing both the sizes and
* initial location of the data.
*
* @param[in,out] operation Handle for newly created operation instance.
*
* @return Error Code
*/
SnpeUdo_ErrorType_t
SnpeUdo_createOperation(SnpeUdo_OpFactory_t opFactory,
void* perOpInfrastructure,
uint32_t numOfInputs,
SnpeUdo_TensorParam_t* inputs,
uint32_t numOfOutputs,
SnpeUdo_TensorParam_t* outputs,
SnpeUdo_Operation_t* operation);
typedef SnpeUdo_ErrorType_t
(*SnpeUdo_CreateOperationFunction_t)(SnpeUdo_OpFactory_t,
void*,
uint32_t,
SnpeUdo_TensorParam_t*,
uint32_t,
SnpeUdo_TensorParam_t*,
SnpeUdo_Operation_t*);
/**
* @brief A pointer to notification function.
*
* The notification function supports the non-blocking (e.g. asynchronous) execution use-case.
* In case an "executeUdoOp" function is called with "blocking" set to zero, and a
* notify function, this function will be called by the implementation library at the
* end of execution. The implementation library will pass the notify function the ID
* that was provided to it when "executeUdoOp" was called.
*
* @param[in] ID 32-bit value, that was provided to executeUdoOp by the calling entity.
* Can be used to track the notifications, in case of multiple execute calls issued.
*
* @return Error code
*
*/
typedef SnpeUdo_ErrorType_t
(*SnpeUdo_ExternalNotify_t)(const uint32_t ID);
/**
* @brief Operation execution function.
*
* Calling this function will run the operation on set of inputs, generating a set of outputs.
* The call can be blocking (synchronous) or non-blocking (asynchronous). To support the
* non-blocking mode, the calling entity can pass an ID and a notification function.
* At the end of the execution this notification function would be called, passing it the ID.
* <b> NOTE: Asynchronous execution mode not supported in this release. </b>
*
* @param[in] operation handle to the operation on which execute is invoked
* @param[in] blocking flag to indicate execution mode.
* If set, execution is blocking,
* e.g SnpeUdo_executeOp call does not return until execution is done.
* If not set, SnpeUdo_executeOp returns immediately, and the
* library will call the notification function (if set) when execution is done.
*
* @param[in] ID 32-bit number that can be used by the calling entity to track execution
* in case of non-blocking execution.
* For example, it can be a sequence number, increased by one on each call.
*
* @param[in] notifyFunc Pointer to notification function. if the pointer is set, and execution is
* non-blocking, the library will call this function at end of execution,
* passing the number provided as ID
*
* @return Error code
*
*/
SnpeUdo_ErrorType_t
SnpeUdo_executeOp(SnpeUdo_Operation_t operation,
bool blocking,
const uint32_t ID,
SnpeUdo_ExternalNotify_t notifyFunc);
typedef SnpeUdo_ErrorType_t
(*SnpeUdo_ExecuteOpFunction_t)(SnpeUdo_Operation_t,
bool,
const uint32_t,
SnpeUdo_ExternalNotify_t);
/**
* @brief A function to setting the inputs & outputs. part of SnpeUdo_Operation struct,
* returned from creation of a new operation instance.
* <b> Not supported in this release. </b>
*
* This function allows the calling entity to change some of the inputs and outputs
* between calls to execute.
* Note that the change is limited to changing the <b> pointer </b> to the tensor data only.
* Any other change may be rejected by the implementation library, causing
* immediate invalidation of the operation instance
*
* @param[in] operation Operation on which IO tensors are set
*
* @param[in] inputs array of tensor parameters. The calling entity may provide a subset of the
* operation inputs, providing only those that it wants to change.
*
* @param[in] outputs array of tensor parameters. The calling entity may provide a subset of the
* operation outputs, providing only those that it wants to change.
*
* @return Error code
*
*/
SnpeUdo_ErrorType_t
SnpeUdo_setOpIO(SnpeUdo_Operation_t operation,
SnpeUdo_TensorParam_t* inputs,
SnpeUdo_TensorParam_t* outputs);
typedef SnpeUdo_ErrorType_t
(*SnpeUdo_SetOpIOFunction_t)(SnpeUdo_Operation_t,
SnpeUdo_TensorParam_t*,
SnpeUdo_TensorParam_t*);
/**
* @brief A function to return execution times.
*
* This function can be called to query the operation execution times on the IP core
* on which the operation is run. The time is provided in micro-seconds
*
* @param[in] operation Handle to operation whose execution time is being profiled
*
* @param[in,out] executionTime pointer to a uint32 value.This function writes the operation
* execution time in usec into this value.
*
* @return Error code
*
*/
SnpeUdo_ErrorType_t
SnpeUdo_profileOp(SnpeUdo_Operation_t operation, uint32_t *executionTime);
typedef SnpeUdo_ErrorType_t
(*SnpeUdo_ProfileOpFunction_t)(SnpeUdo_Operation_t, uint32_t*);
/**
* @brief A function to release the operation instance
* \n When it is called, the implementation library needs to release all resources
* allocated for this operation instance.
* \n Note that all function pointers which are part of SnpeUdo_Operation become
* <b> invalid </b> once releaseUdoOp call returns.
*
* @param[in] operation Handle to operation to be released
* @return Error code
*
*/
SnpeUdo_ErrorType_t
SnpeUdo_releaseOp(SnpeUdo_Operation_t operation);
typedef SnpeUdo_ErrorType_t
(*SnpeUdo_ReleaseOpFunction_t)(SnpeUdo_Operation_t);
/** @} */ /* end_addtogroup c_plus_plus_apis C++ */
#ifdef __cplusplus
} // extern "C"
#endif
#endif //SNPE_UDO_IMPL_H

View File

@ -0,0 +1,44 @@
//==============================================================================
//
// Copyright (c) 2019-2020 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
//
//==============================================================================
// Header to be used by a CPU UDO Implementation library
#ifndef SNPE_UDO_IMPL_CPU_H
#define SNPE_UDO_IMPL_CPU_H
#include <stdio.h>
/** @addtogroup c_plus_plus_apis C++
@{ */
/**
* @brief This struct provides the infrastructure needed by a developer of
* CPU UDO Implementation library.
*
* The framework/runtime which loads the CPU UDO implementation library provides
* this infrastructure data to the loaded library at the time of op factory creation.
* as an opaque pointer. It contains hooks for the UDO library to invoke supported
* functionality at the time of execution
*
* @param getData function pointer to retrieve raw tensor data from opaque pointer
* passed into the UDO when creating an instance.
* @param getDataSize function pointer to retrieve tensor data size from opaque pointer
*/
typedef struct
{
/// function pointer to retrieve raw tensor data from opaque pointer
/// passed into the UDO when creating an instance.
float* (*getData)(void*);
/// function pointer to retrieve tensor data size from opaque pointer
size_t (*getDataSize) (void*);
} SnpeUdo_CpuInfrastructure_t;
/** @} */ /* end_addtogroup c_plus_plus_apis C++ */
#endif // SNPE_UDO_IMPL_CPU_H

View File

@ -0,0 +1,187 @@
//==============================================================================
//
// Copyright (c) 2019-2020 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
//
//==============================================================================
//==============================================================================
/*
* THIS HEADER FILE IS COPIED FROM HEXAGON-NN PROJECT
*
*/
//==============================================================================
// Header to be used by a DSP Hexnn UDO Implementation library
#ifndef SNPE_UDO_IMPL_DSP_H
#define SNPE_UDO_IMPL_DSP_H
#include <stdio.h>
#include "SnpeUdo/UdoImpl.h"
/** @addtogroup c_plus_plus_apis C++
@{ */
/**
* @brief A function to validate that a set of params is supported by an operation
* This function is HexNN specific, use case is when registration library is not in use.
* Optional function.
*
* @param[in] operationType Operation type
* @param[in] numOfStaticParams Number of static params defined by the op
* @param[in] staticParams Array of static params to the op
* @return Error code, indicating if the operation can be created on this set of configuration or not.
*
*/
SnpeUdo_ErrorType_t
SnpeUdo_validateOperation (SnpeUdo_String_t operationType,
uint32_t numOfStaticParams,
const SnpeUdo_Param_t* staticParams);
typedef SnpeUdo_ErrorType_t (*SnpeUdo_ValidateOperationFunction_t) (SnpeUdo_String_t,
uint32_t,
const SnpeUdo_Param_t*);
// enum used for indicating input/outout tensor data layouts on DSP, plain vs d32
typedef enum {
SNPE_UDO_DSP_TENSOR_LAYOUT_PLAIN,
SNPE_UDO_DSP_TENSOR_LAYOUT_D32
} SnpeUdo_HexNNTensorLayout_t;
/**
* @brief A function to query numbers of inputs and outputs,
* quantization type of each input and each output as arrays,
* and data layout (plain vs d32) of each input and each output as arrays
* of an operation.
* inputsQuantTypes and inputsLayouts should point to arrays of size numOfInputs
* outputsQuantTypes and outputsLayouts should point to arrays of size numOfOutputs
*
* Note: inputsLayouts and inputsLayouts can point to NULL, in this case, it is
* assumed all inputs and/or outputs have plain data layouts, i.e. no D32
*
* @param[in] operationType Operation type
* @param[in] numOfStaticParams Number of static params defined by the op
* @param[in] staticParams Array of static params to the op
* @param[in,out] numOfInputs Number of input tensors to the op
* @param[in,out] inputsQuantTypes Array of Quantization info for each input tensor
* @param[in,out] inputsLayouts Array of layout type for each input tensor
* @param[in,out] numOfOutputs Number of output tensors to the op
* @param[in,out] outputsQuantTypes Array of Quantization info for each output tensor
* @param[in,out] outputsLayouts Array of layout type for each output tensor
* @return error code, indicating status of query
*/
SnpeUdo_ErrorType_t
SnpeUdo_queryOperation (SnpeUdo_String_t operationType,
uint32_t numOfStaticParams,
const SnpeUdo_Param_t* staticParams,
uint32_t* numOfInputs,
SnpeUdo_QuantizationType_t** inputsQuantTypes,
SnpeUdo_HexNNTensorLayout_t** inputsLayouts,
uint32_t* numOfOutputs,
SnpeUdo_QuantizationType_t** outputsQuantTypes,
SnpeUdo_HexNNTensorLayout_t** outputsLayouts);
typedef SnpeUdo_ErrorType_t (*SnpeUdo_QueryOperationFunction_t) (SnpeUdo_String_t,
uint32_t,
const SnpeUdo_Param_t*,
uint32_t*,
SnpeUdo_QuantizationType_t**,
SnpeUdo_HexNNTensorLayout_t**,
uint32_t*,
SnpeUdo_QuantizationType_t**,
SnpeUdo_HexNNTensorLayout_t**);
// Global infrastructure functions supported by Hexagon-NN v2
typedef void (*workerThread_t) (void* perOpInfrastructure, void* userData);
typedef int (*udoSetOutputTensorSize_t) (void* perOpInfrastructure, uint32_t outIdx, uint32_t size);
typedef int (*udoGetInputD32Paddings_t) (void* perOpInfrastructure, uint32_t inIdx,
uint32_t* heightPadBefore, uint32_t* heightPadAfter,
uint32_t* widthPadBefore, uint32_t* widthPadAfter,
uint32_t* depthPadBefore, uint32_t* depthPadAfter);
typedef int (*udoSetOutputD32ShapeSizePaddings_t) (void* perOpInfrastructure, uint32_t outIdx,
uint32_t batch,
uint32_t height, uint32_t heightPadBefore, uint32_t heightPadAfter,
uint32_t width, uint32_t widthPadBefore, uint32_t widthPadAfter,
uint32_t depth, uint32_t depthPadBefore, uint32_t depthPadAfter,
SnpeUdo_DataType_t dataType);
typedef void* (*udoMemalign_t) (size_t n, size_t size);
typedef void* (*udoMalloc_t) (size_t size);
typedef void* (*udoCalloc_t) (size_t n, size_t size);
typedef void (*udoFree_t) (void* ptr);
typedef uint32_t (*udoGetVtcmSize_t) (void* perOpInfrastructure);
typedef void* (*udoGetVtcmPtr_t) (void* perOpInfrastructure);
typedef uint32_t (*udoVtcmIsReal_t) (void* perOpInfrastructure);
typedef void (*udoRunWorkerThreads_t) (void* perOpInfrastructure, uint32_t nThreads, workerThread_t w, void* userData);
typedef struct hexNNv2GlobalInfra {
udoSetOutputTensorSize_t udoSetOutputTensorSize;
udoGetInputD32Paddings_t udoGetInputD32Paddings;
udoSetOutputD32ShapeSizePaddings_t udoSetOutputD32ShapeSizePaddings;
udoMemalign_t udoMemalign;
udoMalloc_t udoMalloc;
udoCalloc_t udoCalloc;
udoFree_t udoFree;
udoGetVtcmSize_t udoGetVtcmSize;
udoGetVtcmPtr_t udoGetVtcmPtr;
udoVtcmIsReal_t udoVtcmIsReal;
udoRunWorkerThreads_t udoRunWorkerThreads;
} SnpeUdo_HexNNv2GlobalInfra_t;
// hexnn types
typedef enum hexnnInfraType {
UDO_INFRA_HEXNN_V2,
UDO_INFRA_HEXNN_V3 // reserved, do not use
} SnpeUdo_HexNNInfraType_t;
/**
* @brief Infrastructures needed by a developer of DSP Hexnn UDO Implementation library.
*
* The framework/runtime which loads the Hexnn UDO implementation library provides
* this infrastructure to the loaded library by calling "SnpeUdo_initImplLibrary"
* function, and passing it (cast to void*). The Hexnn UDO library is expected
* to cast it back to this structure.
*
*/
typedef struct dspGlobalInfrastructure {
SnpeUdo_Version_t dspInfraVersion; // api version
SnpeUdo_HexNNInfraType_t infraType;
SnpeUdo_HexNNv2GlobalInfra_t hexNNv2Infra;
} SnpeUdo_DspGlobalInfrastructure_t;
/**
* hexnn v2 per op factory infrastructure
*
* The framework/runtime passes per op factory infrastructure as a void pointer
* to HexNN UDO implementation library by calling function "SnpeUdo_createOpFactory".
* UDO implementation library is expected to cast it back to this following struct.
*
*/
typedef struct hexnnv2OpFactoryInfra {
unsigned long graphId;
} SnpeUdo_HexNNv2OpFactoryInfra_t;
/**
* hexnn v2 per operation infrastructure
*
* The framework/runtime passes per operation infrastructure as a void pointer
* to HexNN UDO implementation library by calling function "SnpeUdo_createOperation".
* UDO implementation library is expected to cast it to the following type and save it.
*
* This is needed to be passed back into some functions from global infrastructure.
*
*/
typedef void* SnpeUdo_HexNNv2OpInfra_t;
/** @} */ /* end_addtogroup c_plus_plus_apis C++ */
#endif // SNPE_UDO_IMPL_DSP_H

View File

@ -0,0 +1,112 @@
//==============================================================================
//
// Copyright (c) 2019-2020 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
//
//==============================================================================
// Header to be used by a GPU UDO Implementation library
#ifndef SNPE_UDO_IMPL_GPU_H
#define SNPE_UDO_IMPL_GPU_H
#include "CL/cl.h"
#include "SnpeUdo/UdoBase.h"
/** @addtogroup c_plus_plus_apis C++
@{ */
/**
* This header defines version 0.0.0 of the GPU UDO Infrastructure.
* It defines the interpretation of the global and per-OpFactory infrastructure pointers
* as well as the interpretation of tensorData pointers.
*
* The per-Operation infrastructure pointer is defined to be null, and should not be used.
*
* The SnpeUdoTensorParam_t struct below provides the interpretation for
* the tensorData opaque pointer for SnpeUdoTensorParams representing inputs or outputs.
*
* The tensorData opaque pointer populated in SnpeUdoScalarParam_t structs should be interpreted
* as a host-readable data pointer.
*
*/
/**
* @brief Function to retrieve opencl program from Program Cache repository.
* @param programCache is opaque pointer to Program Cache repository provided by
* SNPE GPU UDO runtime.
* @param programName is name associated with opencl program for UDO.
* @param program is pointer to opencl program which will be populated with
* valid opencl program if found in Program Cache repository.
* @return SnpeUdo_ErrorType_t is error type returned. SNPE_UDO_NO_ERROR is returned
* on success.
*/
typedef SnpeUdo_ErrorType_t (*SnpeUdo_getProgram_t)
(void* programCache, const char* programName, cl_program* program);
/**
* @brief Function to store valid opencl program in Program Cache repository.
* @param programCache is opaque pointer to Program Cache repository provided by
* SNPE GPU UDO runtime.
* @param programName is name associated with opencl program for UDO.
* @param program is valid opencl program after program is built.
* @return SnpeUdo_ErrorType_t is error type returned. SNPE_UDO_NO_ERROR is returned
* on success.
* */
typedef SnpeUdo_ErrorType_t (*SnpeUdo_storeProgram_t)
(void* programCache, const char * programName, cl_program program);
/**
* @brief Global Infrastructure Definition for GPU UDO Implementations.
*/
typedef struct {
// Infrastructure definition version. This header is 0.0.0
SnpeUdo_Version_t gpuInfraVersion;
SnpeUdo_getProgram_t SnpeUdo_getProgram;
SnpeUdo_storeProgram_t SnpeUdo_storeProgram;
} SnpeUdo_GpuInfrastructure_t;
/**
* @brief Per OpFactory Infrastructure Definition for GPU UDO Implementations.
* @note This version of the infrastructure definition guarantees that the same
* Per OpFactory infrastructure pointer will be provided to all OpFactories
* in the same network.
*/
typedef struct
{
cl_context context;
cl_command_queue commandQueue;
void* programCache;
} SnpeUdo_GpuOpFactoryInfrastructure_t;
/**
* @brief Opaque tensorData definition for operation inputs and outputs.
*
* The following is a list of all SnpeUdoTensorLayout_t values supported by the
* GPU UDO implementation, and how the parameters of the struct should be
* interpreted in each case:
*
* SNPE_UDO_LAYOUT_NHWC:
* mem shall be single-element array, pointing to a cl buffer memory object.
* the dimensions of this object match the dimensions specified in the encompassing
* SnpeUdoTensorParam_t's currDimensions.
*
* memCount shall be 1.
*
* paddedRank and paddedDimensions are undefined and shall be ignored by the UDO
* implementation.
*
*/
typedef struct
{
cl_mem* mem;
uint32_t memCount;
uint32_t paddedRank;
uint32_t* paddedDimensions;
} SnpeUdo_GpuTensorData_t;
/** @} */ /* end_addtogroup c_plus_plus_apis C++ */
#endif // SNPE_UDO_IMPL_GPU_H

View File

@ -0,0 +1,108 @@
//==============================================================================
//
// Copyright (c) 2019-2020 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
//
//==============================================================================
#ifndef SNPE_UDO_REG_H
#define SNPE_UDO_REG_H
#include "SnpeUdo/UdoShared.h"
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup c_plus_plus_apis C++
@{ */
/**
* @brief Initialize the shared library's data structures. Calling any other
* library function before this one will result in an error being returned.
*
* @return Error code
*/
SnpeUdo_ErrorType_t
SnpeUdo_initRegLibrary(void);
typedef SnpeUdo_ErrorType_t
(*SnpeUdo_InitRegLibraryFunction_t)(void);
/**
* @brief A function to query the API version of the UDO registration library.
* The function populates a SnpeUdo_LibVersion_t struct, which contains a SnpeUdo_Version_t
* struct for API version and library version.
*
* @param[in, out] version A pointer to struct which contains major, minor, teeny information for
* library and api versions.
*
* @return Error code
*/
SnpeUdo_ErrorType_t
SnpeUdo_getRegLibraryVersion(SnpeUdo_LibVersion_t** version);
typedef SnpeUdo_ErrorType_t
(*SnpeUdo_getRegLibraryVersion_t)(SnpeUdo_LibVersion_t** version);
/**
* @brief Release the shared library's data structures, and invalidate any
* handles returned by the library. The behavior of any outstanding
* asynchronous calls made to this library when this function is called
* are undefined. All library functions (except SnpeUdo_InitRegLibrary) will
* return an error after this function has been successfully called.
*
* It should be possible to call SnpeUdo_InitRegLibrary after calling this
* function, and re-initialize the library.
*
* @return Error code
*/
SnpeUdo_ErrorType_t
SnpeUdo_terminateRegLibrary(void);
typedef SnpeUdo_ErrorType_t
(*SnpeUdo_TerminateRegLibraryFunction_t)(void);
/**
* @brief A function to query the info on the UDO set.
* The function populates a structure which contains information about
* the package and operations contained in it.
*
* @param[in, out] registrationInfo A struct which contains information on the set of UDOs
*
* @return Error code
*
*/
SnpeUdo_ErrorType_t
SnpeUdo_getRegInfo(SnpeUdo_RegInfo_t** registrationInfo);
typedef SnpeUdo_ErrorType_t
(*SnpeUdo_GetRegInfoFunction_t)(SnpeUdo_RegInfo_t** registrationInfo);
/**
* @brief A function to validate that a set of params is supported by an operation
* The function receives an operation definition struct, and returns if this configuration is
* supported (e.g. if an operation can be created using this configuration)
*
* @param[in] opDefinition A struct of SnpeUdo_OpDefinition type, containing the information needed to
* validate that an operation can be created with this configuration.
*
* @return Error code, indicating is the operation can be created on this set or not.
*
*/
SnpeUdo_ErrorType_t
SnpeUdo_validateOperation(SnpeUdo_OpDefinition_t* opDefinition);
typedef SnpeUdo_ErrorType_t
(*SnpeUdo_ValidateOperationFunction_t)(SnpeUdo_OpDefinition_t* opDefinition);
/** @} */ /* end_addtogroup c_plus_plus_apis C++ */
#ifdef __cplusplus
} // extern "C"
#endif
#endif //SNPE_UDO_REG_H

View File

@ -0,0 +1,46 @@
//==============================================================================
//
// Copyright (c) 2019-2020 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
//
//==============================================================================
#ifndef SNPE_UDO_SHARED_H
#define SNPE_UDO_SHARED_H
#include "SnpeUdo/UdoBase.h"
#ifdef __cplusplus
extern "C"
{
#endif
/** @addtogroup c_plus_plus_apis C++
@{ */
/**
* @brief A function to return the various versions as they relate to the UDO
* The function returns a struct containing the the following:
* libVersion: the version of the implementation library compiled for the UDO. Set by user
* apiVersion: the version of the UDO API used in compiling the implementation library.
* Set by SNPE
*
* @param[in, out] version A pointer to Version struct of type SnpeUdo_LibVersion_t
*
* @return Error code
*
*/
SnpeUdo_ErrorType_t
SnpeUdo_getVersion (SnpeUdo_LibVersion_t** version);
typedef SnpeUdo_ErrorType_t
(*SnpeUdo_GetVersionFunction_t) (SnpeUdo_LibVersion_t** version);
#ifdef __cplusplus
} // extern "C"
#endif
/** @} */ /* end_addtogroup c_plus_plus_apis C++ */
#endif // SNPE_UDO_SHARED_H

View File

@ -43,6 +43,7 @@ volatile sig_atomic_t do_exit = 0;
bool spoofing_started = false;
bool fake_send = false;
bool connected_once = false;
bool ignition = false;
struct tm get_time(){
time_t rawtime;
@ -70,7 +71,7 @@ void safety_setter_thread() {
return;
};
std::vector<char> value_vin = read_db_bytes("CarVin");
std::vector<char> value_vin = Params().read_db_bytes("CarVin");
if (value_vin.size() > 0) {
// sanity check VIN format
assert(value_vin.size() == 17);
@ -92,7 +93,7 @@ void safety_setter_thread() {
return;
};
params = read_db_bytes("CarParams");
params = Params().read_db_bytes("CarParams");
if (params.size() > 0) break;
usleep(100*1000);
}
@ -123,13 +124,15 @@ bool usb_connect() {
return false;
}
Params params = Params();
if (getenv("BOARDD_LOOPBACK")) {
panda->set_loopback(true);
}
const char *fw_sig_buf = panda->get_firmware_version();
if (fw_sig_buf){
write_db_value("PandaFirmware", fw_sig_buf, 128);
params.write_db_value("PandaFirmware", fw_sig_buf, 128);
// Convert to hex for offroad
char fw_sig_hex_buf[16] = {0};
@ -138,7 +141,7 @@ bool usb_connect() {
fw_sig_hex_buf[2*i+1] = NIBBLE_TO_HEX((uint8_t)fw_sig_buf[i] & 0xF);
}
write_db_value("PandaFirmwareHex", fw_sig_hex_buf, 16);
params.write_db_value("PandaFirmwareHex", fw_sig_hex_buf, 16);
LOGW("fw signature: %.*s", 16, fw_sig_hex_buf);
delete[] fw_sig_buf;
@ -149,7 +152,7 @@ bool usb_connect() {
if (serial_buf) {
size_t serial_sz = strnlen(serial_buf, 16);
write_db_value("PandaDongleId", serial_buf, serial_sz);
params.write_db_value("PandaDongleId", serial_buf, serial_sz);
LOGW("panda serial: %.*s", serial_sz, serial_buf);
delete[] serial_buf;
@ -190,10 +193,8 @@ void can_recv(PubMaster &pm) {
// create message
MessageBuilder msg;
auto event = msg.initEvent();
int recv = panda->can_receive(event);
if (recv){
pm.send("can", msg);
}
panda->can_receive(event);
pm.send("can", msg);
}
void can_send_thread() {
@ -254,7 +255,9 @@ void can_recv_thread() {
useconds_t sleep = remaining / 1000;
usleep(sleep);
} else {
LOGW("missed cycles (%d) %lld", (int)-1*remaining/dt, remaining);
if (ignition){
LOGW("missed cycles (%d) %lld", (int)-1*remaining/dt, remaining);
}
next_frame_time = cur_time;
}
@ -268,6 +271,7 @@ void can_health_thread() {
uint32_t no_ignition_cnt = 0;
bool ignition_last = false;
Params params = Params();
// Broadcast empty health message when panda is not yet connected
while (!panda){
@ -295,7 +299,7 @@ void can_health_thread() {
panda->set_safety_model(cereal::CarParams::SafetyModel::NO_OUTPUT);
}
bool ignition = ((health.ignition_line != 0) || (health.ignition_can != 0));
ignition = ((health.ignition_line != 0) || (health.ignition_can != 0));
if (ignition) {
no_ignition_cnt = 0;
@ -317,9 +321,9 @@ void can_health_thread() {
// clear VIN, CarParams, and set new safety on car start
if (ignition && !ignition_last) {
int result = delete_db_value("CarVin");
int result = params.delete_db_value("CarVin");
assert((result == 0) || (result == ERR_NO_VALUE));
result = delete_db_value("CarParams");
result = params.delete_db_value("CarParams");
assert((result == 0) || (result == ERR_NO_VALUE));
if (!safety_setter_thread_running) {
@ -384,9 +388,6 @@ void hardware_control_thread() {
LOGD("start hardware control thread");
SubMaster sm({"thermal", "frontFrame"});
// Other pandas don't have hardware to control
if (panda->hw_type != cereal::HealthData::HwType::UNO && panda->hw_type != cereal::HealthData::HwType::DOS) return;
uint64_t last_front_frame_t = 0;
uint16_t prev_fan_speed = 999;
uint16_t ir_pwr = 0;
@ -400,15 +401,8 @@ void hardware_control_thread() {
cnt++;
sm.update(1000); // TODO: what happens if EINTR is sent while in sm.update?
if (sm.updated("thermal")){
// Fan speed
uint16_t fan_speed = sm["thermal"].getThermal().getFanSpeed();
if (fan_speed != prev_fan_speed || cnt % 100 == 0){
panda->set_fan_speed(fan_speed);
prev_fan_speed = fan_speed;
}
#ifdef QCOM
if (sm.updated("thermal")){
// Charging mode
bool charging_disabled = sm["thermal"].getThermal().getChargingDisabled();
if (charging_disabled != prev_charging_disabled){
@ -421,7 +415,18 @@ void hardware_control_thread() {
}
prev_charging_disabled = charging_disabled;
}
}
#endif
// Other pandas don't have fan/IR to control
if (panda->hw_type != cereal::HealthData::HwType::UNO && panda->hw_type != cereal::HealthData::HwType::DOS) continue;
if (sm.updated("thermal")){
// Fan speed
uint16_t fan_speed = sm["thermal"].getThermal().getFanSpeed();
if (fan_speed != prev_fan_speed || cnt % 100 == 0){
panda->set_fan_speed(fan_speed);
prev_fan_speed = fan_speed;
}
}
if (sm.updated("frontFrame")){
auto event = sm["frontFrame"];

View File

@ -16,7 +16,7 @@ setup(name='Boardd API Implementation',
],
sources=['boardd_api_impl.pyx'],
language="c++",
extra_compile_args=["-std=c++11"],
extra_compile_args=["-std=c++1z", "-Wno-nullability-completeness"],
)
)
)

View File

@ -321,10 +321,10 @@ int Panda::can_receive(cereal::Event::Builder &event){
uint32_t data[RECV_SIZE/4];
int recv = usb_bulk_read(0x81, (unsigned char*)data, RECV_SIZE);
// return if length is 0
if (recv <= 0) {
return 0;
} else if (recv == RECV_SIZE) {
// Not sure if this can happen
if (recv < 0) recv = 0;
if (recv == RECV_SIZE) {
LOGW("Receive buffer full");
}

View File

@ -1,6 +1,6 @@
Import('env', 'arch', 'cereal', 'messaging', 'common', 'gpucommon', 'visionipc', 'webcam', 'QCOM_REPLAY')
Import('env', 'arch', 'cereal', 'messaging', 'common', 'gpucommon', 'visionipc', 'USE_WEBCAM', 'QCOM_REPLAY')
libs = ['m', 'pthread', common, 'jpeg', 'OpenCL', cereal, messaging, 'czmq', 'zmq', 'capnp', 'kj', visionipc, gpucommon]
libs = ['m', 'pthread', common, 'jpeg', 'OpenCL', cereal, messaging, 'zmq', 'capnp', 'kj', visionipc, gpucommon]
if arch == "aarch64":
libs += ['gsl', 'CB', 'adreno_utils', 'EGL', 'GLESv3', 'cutils', 'ui']
@ -9,14 +9,14 @@ if arch == "aarch64":
else:
cameras = ['cameras/camera_qcom.cc']
elif arch == "larch64":
libs += []
cameras = ['cameras/camera_qcom2.c']
libs += ['atomic']
cameras = ['cameras/camera_qcom2.cc']
# no screen
# env = env.Clone()
# env.Append(CXXFLAGS = '-DNOSCREEN')
# env.Append(CFLAGS = '-DNOSCREEN')
else:
if webcam:
if USE_WEBCAM:
libs += ['opencv_core', 'opencv_highgui', 'opencv_imgproc', 'opencv_videoio']
cameras = ['cameras/camera_webcam.cc']
env = env.Clone()
@ -36,6 +36,7 @@ env.SharedLibrary('snapshot/visionipc',
env.Program('camerad', [
'main.cc',
'cameras/camera_common.cc',
'transforms/rgb_to_yuv.c',
'imgproc/utils.cc',
cameras,

View File

@ -1,8 +0,0 @@
#ifndef _SELFDRIVE_VISIOND_VISIOND_H_
#define _SELFDRIVE_VISIOND_VISIOND_H_
#include <inttypes.h>
typedef struct { uint8_t *y, *u, *v; } YUVBuf;
#endif // _SELFDRIVE_VISIOND_VISIOND_H_

View File

@ -0,0 +1,413 @@
#include <thread>
#include <stdio.h>
#include <signal.h>
#include <assert.h>
#include <unistd.h>
#if defined(QCOM) && !defined(QCOM_REPLAY)
#include "cameras/camera_qcom.h"
#elif QCOM2
#include "cameras/camera_qcom2.h"
#elif WEBCAM
#include "cameras/camera_webcam.h"
#else
#include "cameras/camera_frame_stream.h"
#endif
#include "camera_common.h"
#include <libyuv.h>
#include <jpeglib.h>
#include "clutil.h"
#include "common/params.h"
#include "common/swaglog.h"
#include "common/util.h"
#include "imgproc/utils.h"
static cl_program build_debayer_program(cl_device_id device_id, cl_context context, const CameraInfo *ci, const CameraBuf *b) {
char args[4096];
snprintf(args, sizeof(args),
"-cl-fast-relaxed-math -cl-denorms-are-zero "
"-DFRAME_WIDTH=%d -DFRAME_HEIGHT=%d -DFRAME_STRIDE=%d "
"-DRGB_WIDTH=%d -DRGB_HEIGHT=%d -DRGB_STRIDE=%d "
"-DBAYER_FLIP=%d -DHDR=%d",
ci->frame_width, ci->frame_height, ci->frame_stride,
b->rgb_width, b->rgb_height, b->rgb_stride,
ci->bayer_flip, ci->hdr);
#ifdef QCOM2
return CLU_LOAD_FROM_FILE(context, device_id, "cameras/real_debayer.cl", args);
#else
return CLU_LOAD_FROM_FILE(context, device_id, "cameras/debayer.cl", args);
#endif
}
void CameraBuf::init(cl_device_id device_id, cl_context context, CameraState *s, int frame_cnt,
const char *name, release_cb relase_callback) {
const CameraInfo *ci = &s->ci;
camera_state = s;
frame_buf_count = frame_cnt;
frame_size = ci->frame_height * ci->frame_stride;
camera_bufs = std::make_unique<VisionBuf[]>(frame_buf_count);
camera_bufs_metadata = std::make_unique<FrameMetadata[]>(frame_buf_count);
for (int i = 0; i < frame_buf_count; i++) {
camera_bufs[i] = visionbuf_allocate_cl(frame_size, device_id, context);
}
rgb_width = ci->frame_width;
rgb_height = ci->frame_height;
#ifndef QCOM2
// debayering does a 2x downscale
if (ci->bayer) {
rgb_width = ci->frame_width / 2;
rgb_height = ci->frame_height / 2;
}
float db_s = 0.5;
#else
float db_s = 1.0;
#endif
if (ci->bayer) {
yuv_transform = transform_scale_buffer(s->transform, db_s);
} else {
yuv_transform = s->transform;
}
for (int i = 0; i < UI_BUF_COUNT; i++) {
VisionImg img = visionimg_alloc_rgb24(device_id, context, rgb_width, rgb_height, &rgb_bufs[i]);
if (i == 0) {
rgb_stride = img.stride;
}
}
tbuffer_init(&ui_tb, UI_BUF_COUNT, name);
tbuffer_init2(&camera_tb, frame_buf_count, "frame", relase_callback, s);
// yuv back for recording and orbd
pool_init(&yuv_pool, YUV_COUNT);
yuv_tb = pool_get_tbuffer(&yuv_pool);
yuv_width = rgb_width;
yuv_height = rgb_height;
yuv_buf_size = rgb_width * rgb_height * 3 / 2;
for (int i = 0; i < YUV_COUNT; i++) {
yuv_ion[i] = visionbuf_allocate_cl(yuv_buf_size, device_id, context);
yuv_bufs[i].y = (uint8_t *)yuv_ion[i].addr;
yuv_bufs[i].u = yuv_bufs[i].y + (yuv_width * yuv_height);
yuv_bufs[i].v = yuv_bufs[i].u + (yuv_width / 2 * yuv_height / 2);
}
int err;
if (ci->bayer) {
cl_program prg_debayer = build_debayer_program(device_id, context, ci, this);
krnl_debayer = clCreateKernel(prg_debayer, "debayer10", &err);
assert(err == 0);
assert(clReleaseProgram(prg_debayer) == 0);
}
rgb_to_yuv_init(&rgb_to_yuv_state, context, device_id, yuv_width, yuv_height, rgb_stride);
#ifdef __APPLE__
q = clCreateCommandQueue(context, device_id, 0, &err);
#else
const cl_queue_properties props[] = {0}; //CL_QUEUE_PRIORITY_KHR, CL_QUEUE_PRIORITY_HIGH_KHR, 0};
q = clCreateCommandQueueWithProperties(context, device_id, props, &err);
#endif
assert(err == 0);
}
CameraBuf::~CameraBuf() {
for (int i = 0; i < frame_buf_count; i++) {
visionbuf_free(&camera_bufs[i]);
}
for (int i = 0; i < UI_BUF_COUNT; i++) {
visionbuf_free(&rgb_bufs[i]);
}
for (int i = 0; i < YUV_COUNT; i++) {
visionbuf_free(&yuv_ion[i]);
}
clReleaseKernel(krnl_debayer);
clReleaseCommandQueue(q);
}
bool CameraBuf::acquire() {
const int buf_idx = tbuffer_acquire(&camera_tb);
if (buf_idx < 0) {
return false;
}
const FrameMetadata &frame_data = camera_bufs_metadata[buf_idx];
if (frame_data.frame_id == -1) {
LOGE("no frame data? wtf");
tbuffer_release(&camera_tb, buf_idx);
return false;
}
cur_frame_data = frame_data;
cur_rgb_idx = tbuffer_select(&ui_tb);
cur_rgb_buf = &rgb_bufs[cur_rgb_idx];
cl_event debayer_event;
cl_mem camrabuf_cl = camera_bufs[buf_idx].buf_cl;
if (camera_state->ci.bayer) {
assert(clSetKernelArg(krnl_debayer, 0, sizeof(cl_mem), &camrabuf_cl) == 0);
assert(clSetKernelArg(krnl_debayer, 1, sizeof(cl_mem), &cur_rgb_buf->buf_cl) == 0);
#ifdef QCOM2
assert(clSetKernelArg(krnl_debayer, 2, camera_state->debayer_cl_localMemSize, 0) == 0);
assert(clEnqueueNDRangeKernel(q, krnl_debayer, 2, NULL,
camera_state->debayer_cl_globalWorkSize, camera_state->debayer_cl_localWorkSize,
0, 0, &debayer_event) == 0);
#else
float digital_gain = camera_state->digital_gain;
if ((int)digital_gain == 0) {
digital_gain = 1.0;
}
assert(clSetKernelArg(krnl_debayer, 2, sizeof(float), &digital_gain) == 0);
const size_t debayer_work_size = rgb_height; // doesn't divide evenly, is this okay?
const size_t debayer_local_work_size = 128;
assert(clEnqueueNDRangeKernel(q, krnl_debayer, 1, NULL,
&debayer_work_size, &debayer_local_work_size, 0, 0, &debayer_event) == 0);
#endif
} else {
assert(cur_rgb_buf->len >= frame_size);
assert(rgb_stride == camera_state->ci.frame_stride);
assert(clEnqueueCopyBuffer(q, camrabuf_cl, cur_rgb_buf->buf_cl, 0, 0,
cur_rgb_buf->len, 0, 0, &debayer_event) == 0);
}
clWaitForEvents(1, &debayer_event);
clReleaseEvent(debayer_event);
tbuffer_release(&camera_tb, buf_idx);
visionbuf_sync(cur_rgb_buf, VISIONBUF_SYNC_FROM_DEVICE);
cur_yuv_idx = pool_select(&yuv_pool);
yuv_metas[cur_yuv_idx] = frame_data;
rgb_to_yuv_queue(&rgb_to_yuv_state, q, cur_rgb_buf->buf_cl, yuv_ion[cur_yuv_idx].buf_cl);
visionbuf_sync(&yuv_ion[cur_yuv_idx], VISIONBUF_SYNC_FROM_DEVICE);
// keep another reference around till were done processing
pool_acquire(&yuv_pool, cur_yuv_idx);
pool_push(&yuv_pool, cur_yuv_idx);
return true;
}
void CameraBuf::release() {
tbuffer_dispatch(&ui_tb, cur_rgb_idx);
pool_release(&yuv_pool, cur_yuv_idx);
}
void CameraBuf::stop() {
tbuffer_stop(&ui_tb);
tbuffer_stop(&camera_tb);
pool_stop(&yuv_pool);
}
// common functions
void fill_frame_data(cereal::FrameData::Builder &framed, const FrameMetadata &frame_data, uint32_t cnt) {
framed.setFrameId(frame_data.frame_id);
framed.setEncodeId(cnt);
framed.setTimestampEof(frame_data.timestamp_eof);
framed.setFrameLength(frame_data.frame_length);
framed.setIntegLines(frame_data.integ_lines);
framed.setGlobalGain(frame_data.global_gain);
framed.setLensPos(frame_data.lens_pos);
framed.setLensSag(frame_data.lens_sag);
framed.setLensErr(frame_data.lens_err);
framed.setLensTruePos(frame_data.lens_true_pos);
framed.setGainFrac(frame_data.gain_frac);
}
void create_thumbnail(MultiCameraState *s, CameraState *c, uint8_t *bgr_ptr) {
const CameraBuf *b = &c->buf;
uint8_t* thumbnail_buffer = NULL;
unsigned long thumbnail_len = 0;
unsigned char *row = (unsigned char *)malloc(b->rgb_width/4*3);
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
jpeg_mem_dest(&cinfo, &thumbnail_buffer, &thumbnail_len);
cinfo.image_width = b->rgb_width / 4;
cinfo.image_height = b->rgb_height / 4;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults(&cinfo);
#ifndef __APPLE__
jpeg_set_quality(&cinfo, 50, true);
jpeg_start_compress(&cinfo, true);
#else
jpeg_set_quality(&cinfo, 50, static_cast<boolean>(true) );
jpeg_start_compress(&cinfo, static_cast<boolean>(true) );
#endif
JSAMPROW row_pointer[1];
for (int ii = 0; ii < b->rgb_height/4; ii+=1) {
for (int j = 0; j < b->rgb_width*3; j+=12) {
for (int k = 0; k < 3; k++) {
uint16_t dat = 0;
int i = ii * 4;
dat += bgr_ptr[b->rgb_stride*i + j + k];
dat += bgr_ptr[b->rgb_stride*i + j+3 + k];
dat += bgr_ptr[b->rgb_stride*(i+1) + j + k];
dat += bgr_ptr[b->rgb_stride*(i+1) + j+3 + k];
dat += bgr_ptr[b->rgb_stride*(i+2) + j + k];
dat += bgr_ptr[b->rgb_stride*(i+2) + j+3 + k];
dat += bgr_ptr[b->rgb_stride*(i+3) + j + k];
dat += bgr_ptr[b->rgb_stride*(i+3) + j+3 + k];
row[(j/4) + (2-k)] = dat/8;
}
}
row_pointer[0] = row;
jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
free(row);
jpeg_finish_compress(&cinfo);
MessageBuilder msg;
auto thumbnaild = msg.initEvent().initThumbnail();
thumbnaild.setFrameId(b->cur_frame_data.frame_id);
thumbnaild.setTimestampEof(b->cur_frame_data.timestamp_eof);
thumbnaild.setThumbnail(kj::arrayPtr((const uint8_t*)thumbnail_buffer, thumbnail_len));
if (s->pm != NULL) {
s->pm->send("thumbnail", msg);
}
}
void set_exposure_target(CameraState *c, const uint8_t *pix_ptr, bool front, int x_start, int x_end, int x_skip, int y_start, int y_end, int y_skip) {
const CameraBuf *b = &c->buf;
uint32_t lum_binning[256] = {0};
for (int y = y_start; y < y_end; y += y_skip) {
for (int x = x_start; x < x_end; x += x_skip) {
if (!front) {
uint8_t lum = pix_ptr[(y * b->yuv_width) + x];
lum_binning[lum]++;
} else {
const uint8_t *pix = &pix_ptr[y * b->rgb_width * 3 + x * 3];
unsigned int lum = (unsigned int)(pix[0] + pix[1] + pix[2]);
lum_binning[std::min(lum / 3, 255u)]++;
}
}
}
unsigned int lum_total = (y_end - y_start) * (x_end - x_start) / x_skip / y_skip;
unsigned int lum_cur = 0;
int lum_med = 0;
int lum_med_alt = 0;
for (lum_med=255; lum_med>=0; lum_med--) {
lum_cur += lum_binning[lum_med];
#ifdef QCOM2
bool reach_hlc_perc = false;
if (c->camera_num == 0) { // wide
reach_hlc_perc = lum_cur > 2*lum_total / (3*HLC_A);
} else {
reach_hlc_perc = lum_cur > lum_total / HLC_A;
}
if (reach_hlc_perc && lum_med > HLC_THRESH) {
lum_med_alt = 86;
}
#endif
if (lum_cur >= lum_total / 2) {
break;
}
}
lum_med = lum_med_alt>lum_med?lum_med_alt:lum_med;
camera_autoexposure(c, lum_med / 256.0);
}
extern volatile sig_atomic_t do_exit;
void *processing_thread(MultiCameraState *cameras, const char *tname,
CameraState *cs, int priority, process_thread_cb callback) {
set_thread_name(tname);
int err = set_realtime_priority(priority);
LOG("%s start! setpriority returns %d", tname, err);
for (int cnt = 0; !do_exit; cnt++) {
if (!cs->buf.acquire()) continue;
callback(cameras, cs, cnt);
cs->buf.release();
}
return NULL;
}
std::thread start_process_thread(MultiCameraState *cameras, const char *tname,
CameraState *cs, int priority, process_thread_cb callback) {
return std::thread(processing_thread, cameras, tname, cs, priority, callback);
}
void common_camera_process_front(SubMaster *sm, PubMaster *pm, CameraState *c, int cnt) {
const CameraBuf *b = &c->buf;
static int meteringbox_xmin = 0, meteringbox_xmax = 0;
static int meteringbox_ymin = 0, meteringbox_ymax = 0;
static const bool rhd_front = Params().read_db_bool("IsRHD");
sm->update(0);
if (sm->updated("driverState")) {
auto state = (*sm)["driverState"].getDriverState();
float face_prob = state.getFaceProb();
float face_position[2];
face_position[0] = state.getFacePosition()[0];
face_position[1] = state.getFacePosition()[1];
// set front camera metering target
if (face_prob > 0.4) {
int x_offset = rhd_front ? 0:b->rgb_width - 0.5 * b->rgb_height;
meteringbox_xmin = x_offset + (face_position[0] + 0.5) * (0.5 * b->rgb_height) - 72;
meteringbox_xmax = x_offset + (face_position[0] + 0.5) * (0.5 * b->rgb_height) + 72;
meteringbox_ymin = (face_position[1] + 0.5) * (b->rgb_height) - 72;
meteringbox_ymax = (face_position[1] + 0.5) * (b->rgb_height) + 72;
} else { // use default setting if no face
meteringbox_ymin = b->rgb_height * 1 / 3;
meteringbox_ymax = b->rgb_height * 1;
meteringbox_xmin = rhd_front ? 0:b->rgb_width * 3 / 5;
meteringbox_xmax = rhd_front ? b->rgb_width * 2 / 5:b->rgb_width;
}
}
// auto exposure
if (cnt % 3 == 0) {
// use driver face crop for AE
int x_start, x_end, y_start, y_end;
int skip = 1;
if (meteringbox_xmax > 0) {
x_start = std::max(0, meteringbox_xmin);
x_end = std::min(b->rgb_width - 1, meteringbox_xmax);
y_start = std::max(0, meteringbox_ymin);
y_end = std::min(b->rgb_height - 1, meteringbox_ymax);
} else {
y_start = b->rgb_height * 1 / 3;
y_end = b->rgb_height * 1;
x_start = rhd_front ? 0 : b->rgb_width * 3 / 5;
x_end = rhd_front ? b->rgb_width * 2 / 5 : b->rgb_width;
}
#ifdef QCOM2
x_start = 96;
x_end = 1832;
y_start = 242;
y_end = 1148;
skip = 4;
#endif
set_exposure_target(c, (const uint8_t *)b->cur_rgb_buf->addr, 1, x_start, x_end, 2, y_start, y_end, skip);
}
MessageBuilder msg;
auto framed = msg.initEvent().initFrontFrame();
framed.setFrameType(cereal::FrameData::FrameType::FRONT);
fill_frame_data(framed, b->cur_frame_data, cnt);
pm->send("frontFrame", msg);
}

View File

@ -1,8 +1,19 @@
#ifndef CAMERA_COMMON_H
#define CAMERA_COMMON_H
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include <stdint.h>
#include <memory>
#include <thread>
#include "common/buffering.h"
#include "common/mat.h"
#include "common/swaglog.h"
#include "common/visionbuf.h"
#include "common/visionimg.h"
#include "imgproc/utils.h"
#include "messaging.hpp"
#include "transforms/rgb_to_yuv.h"
#include "common/visionipc.h"
#define CAMERA_ID_IMX298 0
#define CAMERA_ID_IMX179 1
@ -15,9 +26,13 @@
#define CAMERA_ID_AR0231 8
#define CAMERA_ID_MAX 9
#ifdef __cplusplus
extern "C" {
#endif
#define UI_BUF_COUNT 4
#define YUV_COUNT 40
#define LOG_CAMERA_ID_FCAMERA 0
#define LOG_CAMERA_ID_DCAMERA 1
#define LOG_CAMERA_ID_ECAMERA 2
#define LOG_CAMERA_ID_QCAMERA 3
#define LOG_CAMERA_ID_MAX 4
typedef struct CameraInfo {
const char* name;
@ -28,6 +43,19 @@ typedef struct CameraInfo {
bool hdr;
} CameraInfo;
typedef struct LogCameraInfo {
const char* filename;
const char* frame_packet_name;
const char* encode_idx_name;
VisionStreamType stream_type;
int frame_width, frame_height;
int fps;
int bitrate;
bool is_h265;
bool downscale;
bool has_qcamera;
} LogCameraInfo;
typedef struct FrameMetadata {
uint32_t frame_id;
uint64_t timestamp_eof;
@ -41,10 +69,67 @@ typedef struct FrameMetadata {
float gain_frac;
} FrameMetadata;
typedef struct CameraExpInfo {
int op_id;
float grey_frac;
} CameraExpInfo;
extern CameraInfo cameras_supported[CAMERA_ID_MAX];
#ifdef __cplusplus
}
#endif
typedef struct {
uint8_t *y, *u, *v;
} YUVBuf;
#endif
struct MultiCameraState;
struct CameraState;
typedef void (*release_cb)(void *cookie, int buf_idx);
class CameraBuf {
public:
CameraState *camera_state;
cl_kernel krnl_debayer;
cl_command_queue q;
Pool yuv_pool;
VisionBuf yuv_ion[YUV_COUNT];
YUVBuf yuv_bufs[YUV_COUNT];
FrameMetadata yuv_metas[YUV_COUNT];
size_t yuv_buf_size;
int yuv_width, yuv_height;
RGBToYUVState rgb_to_yuv_state;
int rgb_width, rgb_height, rgb_stride;
VisionBuf rgb_bufs[UI_BUF_COUNT];
mat3 yuv_transform;
int cur_yuv_idx, cur_rgb_idx;
FrameMetadata cur_frame_data;
VisionBuf *cur_rgb_buf;
std::unique_ptr<VisionBuf[]> camera_bufs;
std::unique_ptr<FrameMetadata[]> camera_bufs_metadata;
TBuffer camera_tb, ui_tb;
TBuffer *yuv_tb; // only for visionserver
CameraBuf() = default;
~CameraBuf();
void init(cl_device_id device_id, cl_context context, CameraState *s, int frame_cnt,
const char *name = "frame", release_cb relase_callback = nullptr);
bool acquire();
void release();
void stop();
int frame_buf_count;
int frame_size;
};
typedef void (*process_thread_cb)(MultiCameraState *s, CameraState *c, int cnt);
void fill_frame_data(cereal::FrameData::Builder &framed, const FrameMetadata &frame_data, uint32_t cnt);
void create_thumbnail(MultiCameraState *s, CameraState *c, uint8_t *bgr_ptr);
void set_exposure_target(CameraState *c, const uint8_t *pix_ptr, bool front, int x_start, int x_end, int x_skip, int y_start, int y_end, int y_skip);
std::thread start_process_thread(MultiCameraState *cameras, const char *tname,
CameraState *cs, int priority, process_thread_cb callback);
void common_camera_process_front(SubMaster *sm, PubMaster *pm, CameraState *c, int cnt);

View File

@ -23,41 +23,35 @@ extern volatile sig_atomic_t do_exit;
#define FRAME_HEIGHT 874
namespace {
void camera_open(CameraState *s, VisionBuf *camera_bufs, bool rear) {
assert(camera_bufs);
s->camera_bufs = camera_bufs;
void camera_open(CameraState *s, bool rear) {
}
void camera_close(CameraState *s) {
tbuffer_stop(&s->camera_tb);
s->buf.stop();
}
void camera_release_buffer(void *cookie, int buf_idx) {}
void camera_init(CameraState *s, int camera_id, unsigned int fps) {
void camera_init(CameraState *s, int camera_id, unsigned int fps, cl_device_id device_id, cl_context ctx) {
assert(camera_id < ARRAYSIZE(cameras_supported));
s->ci = cameras_supported[camera_id];
assert(s->ci.frame_width != 0);
s->frame_size = s->ci.frame_height * s->ci.frame_stride;
s->fps = fps;
tbuffer_init2(&s->camera_tb, FRAME_BUF_COUNT, "frame", camera_release_buffer, s);
s->buf.init(device_id, ctx, s, FRAME_BUF_COUNT, "camera");
}
void run_frame_stream(MultiCameraState *s) {
SubMaster sm({"frame"});
s->sm = new SubMaster({"frame"});
CameraState *const rear_camera = &s->rear;
auto *tb = &rear_camera->camera_tb;
auto *tb = &rear_camera->buf.camera_tb;
while (!do_exit) {
if (sm.update(1000) == 0) continue;
if (s->sm->update(1000) == 0) continue;
auto frame = sm["frame"].getFrame();
auto frame = (*(s->sm))["frame"].getFrame();
const int buf_idx = tbuffer_select(tb);
rear_camera->camera_bufs_metadata[buf_idx] = {
rear_camera->buf.camera_bufs_metadata[buf_idx] = {
.frame_id = frame.getFrameId(),
.timestamp_eof = frame.getTimestampEof(),
.frame_length = static_cast<unsigned>(frame.getFrameLength()),
@ -65,8 +59,8 @@ void run_frame_stream(MultiCameraState *s) {
.global_gain = static_cast<unsigned>(frame.getGlobalGain()),
};
cl_command_queue q = rear_camera->camera_bufs[buf_idx].copy_q;
cl_mem yuv_cl = rear_camera->camera_bufs[buf_idx].buf_cl;
cl_command_queue q = rear_camera->buf.camera_bufs[buf_idx].copy_q;
cl_mem yuv_cl = rear_camera->buf.camera_bufs[buf_idx].buf_cl;
clEnqueueWriteBuffer(q, yuv_cl, CL_TRUE, 0, frame.getImage().size(), frame.getImage().begin(), 0, NULL, NULL);
tbuffer_dispatch(tb, buf_idx);
@ -93,15 +87,15 @@ CameraInfo cameras_supported[CAMERA_ID_MAX] = {
},
};
void cameras_init(MultiCameraState *s) {
camera_init(&s->rear, CAMERA_ID_IMX298, 20);
void cameras_init(MultiCameraState *s, cl_device_id device_id, cl_context ctx) {
camera_init(&s->rear, CAMERA_ID_IMX298, 20, device_id, ctx);
s->rear.transform = (mat3){{
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0,
}};
camera_init(&s->front, CAMERA_ID_OV8865, 10);
camera_init(&s->front, CAMERA_ID_OV8865, 10, device_id, ctx);
s->front.transform = (mat3){{
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
@ -111,25 +105,27 @@ void cameras_init(MultiCameraState *s) {
void camera_autoexposure(CameraState *s, float grey_frac) {}
void cameras_open(MultiCameraState *s, VisionBuf *camera_bufs_rear,
VisionBuf *camera_bufs_focus, VisionBuf *camera_bufs_stats,
VisionBuf *camera_bufs_front) {
assert(camera_bufs_rear);
assert(camera_bufs_front);
void cameras_open(MultiCameraState *s) {
// LOG("*** open front ***");
camera_open(&s->front, camera_bufs_front, false);
camera_open(&s->front, false);
// LOG("*** open rear ***");
camera_open(&s->rear, camera_bufs_rear, true);
camera_open(&s->rear, true);
}
void cameras_close(MultiCameraState *s) {
camera_close(&s->rear);
}
// called by processing_thread
void camera_process_rear(MultiCameraState *s, CameraState *c, int cnt) {
// empty
}
void cameras_run(MultiCameraState *s) {
std::thread t = start_process_thread(s, "processing", &s->rear, 51, camera_process_rear);
set_thread_name("frame_streaming");
run_frame_stream(s);
cameras_close(s);
t.join();
}

View File

@ -1,5 +1,4 @@
#ifndef CAMERA_FRAME_STREAM_H
#define CAMERA_FRAME_STREAM_H
#pragma once
#include <stdbool.h>
@ -10,50 +9,35 @@
#include <CL/cl.h>
#endif
#include "common/mat.h"
#include "buffering.h"
#include "common/visionbuf.h"
#include "camera_common.h"
#define FRAME_BUF_COUNT 16
#ifdef __cplusplus
extern "C" {
#endif
typedef struct CameraState {
int camera_id;
CameraInfo ci;
int frame_size;
VisionBuf *camera_bufs;
FrameMetadata camera_bufs_metadata[FRAME_BUF_COUNT];
TBuffer camera_tb;
int fps;
float digital_gain;
float cur_gain_frac;
mat3 transform;
} CameraState;
CameraBuf buf;
} CameraState;
typedef struct MultiCameraState {
int ispif_fd;
CameraState rear;
CameraState front;
SubMaster *sm;
PubMaster *pm;
} MultiCameraState;
void cameras_init(MultiCameraState *s);
void cameras_open(MultiCameraState *s, VisionBuf *camera_bufs_rear, VisionBuf *camera_bufs_focus, VisionBuf *camera_bufs_stats, VisionBuf *camera_bufs_front);
void cameras_init(MultiCameraState *s, cl_device_id device_id, cl_context ctx);
void cameras_open(MultiCameraState *s);
void cameras_run(MultiCameraState *s);
void cameras_close(MultiCameraState *s);
void camera_autoexposure(CameraState *s, float grey_frac);
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@ -4,8 +4,11 @@
#include <assert.h>
#include <unistd.h>
#include <fcntl.h>
#include <math.h>
#include <poll.h>
#include <sys/ioctl.h>
#include <atomic>
#include <algorithm>
#include <linux/media.h>
@ -22,6 +25,7 @@
#include "common/timing.h"
#include "common/swaglog.h"
#include "common/params.h"
#include "clutil.h"
#include "cereal/gen/cpp/log.capnp.h"
@ -30,21 +34,12 @@
#include "camera_qcom.h"
// enable this to run the camera at 60fps and sample every third frame
// supposed to reduce 33ms of lag, but no results
//#define HIGH_FPS
#define CAMERA_MSG_AUTOEXPOSE 0
typedef struct CameraMsg {
int type;
int camera_num;
float grey_frac;
} CameraMsg;
extern volatile sig_atomic_t do_exit;
// global var for AE/AF ops
std::atomic<CameraExpInfo> rear_exp{{0}};
std::atomic<CameraExpInfo> front_exp{{0}};
CameraInfo cameras_supported[CAMERA_ID_MAX] = {
[CAMERA_ID_IMX298] = {
.frame_width = 2328,
@ -106,14 +101,13 @@ static void camera_release_buffer(void* cookie, int buf_idx) {
static void camera_init(CameraState *s, int camera_id, int camera_num,
uint32_t pixel_clock, uint32_t line_length_pclk,
unsigned int max_gain, unsigned int fps) {
unsigned int max_gain, unsigned int fps, cl_device_id device_id, cl_context ctx) {
s->camera_num = camera_num;
s->camera_id = camera_id;
assert(camera_id < ARRAYSIZE(cameras_supported));
s->ci = cameras_supported[camera_id];
assert(s->ci.frame_width != 0);
s->frame_size = s->ci.frame_height * s->ci.frame_stride;
s->pixel_clock = pixel_clock;
s->line_length_pclk = line_length_pclk;
@ -122,12 +116,7 @@ static void camera_init(CameraState *s, int camera_id, int camera_num,
s->self_recover = 0;
s->ops_sock = zsock_new_push(">inproc://cameraops");
assert(s->ops_sock);
s->ops_sock_handle = zsock_resolve(s->ops_sock);
tbuffer_init2(&s->camera_tb, FRAME_BUF_COUNT, "frame",
camera_release_buffer, s);
s->buf.init(device_id, ctx, s, FRAME_BUF_COUNT, "frame", camera_release_buffer);
pthread_mutex_init(&s->frame_info_lock, NULL);
}
@ -233,12 +222,6 @@ static int imx179_s5k3p8sp_apply_exposure(CameraState *s, int gain, int integ_li
//printf("front camera: %d %d %d\n", gain, integ_lines, frame_length);
int err;
if (gain > 448) {
s->digital_gain = (512.0/(512-(gain))) / 8.0;
} else {
s->digital_gain = 1.0;
}
struct msm_camera_i2c_reg_array reg_array[] = {
{0x104,0x1,0},
@ -258,7 +241,18 @@ static int imx179_s5k3p8sp_apply_exposure(CameraState *s, int gain, int integ_li
return err;
}
void cameras_init(MultiCameraState *s) {
cl_program build_conv_program(cl_device_id device_id, cl_context context, int image_w, int image_h, int filter_size) {
char args[4096];
snprintf(args, sizeof(args),
"-cl-fast-relaxed-math -cl-denorms-are-zero "
"-DIMAGE_W=%d -DIMAGE_H=%d -DFLIP_RB=%d "
"-DFILTER_SIZE=%d -DHALF_FILTER_SIZE=%d -DTWICE_HALF_FILTER_SIZE=%d -DHALF_FILTER_SIZE_IMAGE_W=%d",
image_w, image_h, 1,
filter_size, filter_size/2, (filter_size/2)*2, (filter_size/2)*image_w);
return CLU_LOAD_FROM_FILE(context, device_id, "imgproc/conv.cl", args);
}
void cameras_init(MultiCameraState *s, cl_device_id device_id, cl_context ctx) {
char project_name[1024] = {0};
property_get("ro.boot.project_name", project_name, "");
@ -296,29 +290,29 @@ void cameras_init(MultiCameraState *s) {
camera_init(&s->rear, CAMERA_ID_IMX298, 0,
/*pixel_clock=*/600000000, /*line_length_pclk=*/5536,
/*max_gain=*/510, //0 (ISO 100)- 448 (ISO 800, max analog gain) - 511 (super noisy)
/*max_gain=*/510, //0 (ISO 100)- 448 (ISO 800, max analog gain) - 511 (super noisy)
#ifdef HIGH_FPS
/*fps*/60
/*fps*/ 60,
#else
/*fps*/20
/*fps*/ 20,
#endif
);
device_id, ctx);
s->rear.apply_exposure = imx298_apply_exposure;
if (s->device == DEVICE_OP3T) {
camera_init(&s->front, CAMERA_ID_S5K3P8SP, 1,
/*pixel_clock=*/561000000, /*line_length_pclk=*/5120,
/*max_gain=*/510, 10);
/*pixel_clock=*/560000000, /*line_length_pclk=*/5120,
/*max_gain=*/510, 10, device_id, ctx);
s->front.apply_exposure = imx179_s5k3p8sp_apply_exposure;
} else if (s->device == DEVICE_LP3) {
camera_init(&s->front, CAMERA_ID_OV8865, 1,
/*pixel_clock=*/251200000, /*line_length_pclk=*/7000,
/*max_gain=*/510, 10);
/*pixel_clock=*/72000000, /*line_length_pclk=*/1602,
/*max_gain=*/510, 10, device_id, ctx);
s->front.apply_exposure = ov8865_apply_exposure;
} else {
camera_init(&s->front, CAMERA_ID_IMX179, 1,
/*pixel_clock=*/251200000, /*line_length_pclk=*/3440,
/*max_gain=*/224, 20);
/*max_gain=*/224, 20, device_id, ctx);
s->front.apply_exposure = imx179_s5k3p8sp_apply_exposure;
}
@ -338,6 +332,40 @@ void cameras_init(MultiCameraState *s) {
s->rear.device = s->device;
s->front.device = s->device;
s->sm = new SubMaster({"driverState", "sensorEvents"});
s->pm = new PubMaster({"frame", "frontFrame", "thumbnail"});
int err;
const int rgb_width = s->rear.buf.rgb_width;
const int rgb_height = s->rear.buf.rgb_height;
for (int i = 0; i < FRAME_BUF_COUNT; i++) {
// TODO: make lengths correct
s->focus_bufs[i] = visionbuf_allocate(0xb80);
s->stats_bufs[i] = visionbuf_allocate(0xb80);
}
s->prg_rgb_laplacian = build_conv_program(device_id, ctx, rgb_width/NUM_SEGMENTS_X, rgb_height/NUM_SEGMENTS_Y, 3);
s->krnl_rgb_laplacian = clCreateKernel(s->prg_rgb_laplacian, "rgb2gray_conv2d", &err);
assert(err == 0);
// TODO: Removed CL_MEM_SVM_FINE_GRAIN_BUFFER, confirm it doesn't matter
s->rgb_conv_roi_cl = clCreateBuffer(ctx, CL_MEM_READ_WRITE,
rgb_width/NUM_SEGMENTS_X * rgb_height/NUM_SEGMENTS_Y * 3 * sizeof(uint8_t), NULL, NULL);
s->rgb_conv_result_cl = clCreateBuffer(ctx, CL_MEM_READ_WRITE,
rgb_width/NUM_SEGMENTS_X * rgb_height/NUM_SEGMENTS_Y * sizeof(int16_t), NULL, NULL);
s->rgb_conv_filter_cl = clCreateBuffer(ctx, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
9 * sizeof(int16_t), (void*)&lapl_conv_krnl, NULL);
s->conv_cl_localMemSize = ( CONV_LOCAL_WORKSIZE + 2 * (3 / 2) ) * ( CONV_LOCAL_WORKSIZE + 2 * (3 / 2) );
s->conv_cl_localMemSize *= 3 * sizeof(uint8_t);
s->conv_cl_globalWorkSize[0] = rgb_width/NUM_SEGMENTS_X;
s->conv_cl_globalWorkSize[1] = rgb_height/NUM_SEGMENTS_Y;
s->conv_cl_localWorkSize[0] = CONV_LOCAL_WORKSIZE;
s->conv_cl_localWorkSize[1] = CONV_LOCAL_WORKSIZE;
for (int i=0; i<ARRAYSIZE(s->lapres); i++) {s->lapres[i] = 16160;}
const size_t size = (rgb_width/NUM_SEGMENTS_X)*(rgb_height/NUM_SEGMENTS_Y);
s->rgb_roi_buf = std::make_unique<uint8_t[]>(size*3);
s->conv_result = std::make_unique<int16_t[]>(size);
}
static void set_exposure(CameraState *s, float exposure_frac, float gain_frac) {
@ -349,7 +377,7 @@ static void set_exposure(CameraState *s, float exposure_frac, float gain_frac) {
unsigned int integ_lines = s->cur_integ_lines;
if (exposure_frac >= 0) {
exposure_frac = clamp(exposure_frac, 2.0 / frame_length, 1.0);
exposure_frac = std::clamp(exposure_frac, 2.0f / frame_length, 1.0f);
integ_lines = frame_length * exposure_frac;
// See page 79 of the datasheet, this is the max allowed (-1 for phase adjust)
@ -358,7 +386,7 @@ static void set_exposure(CameraState *s, float exposure_frac, float gain_frac) {
if (gain_frac >= 0) {
// ISO200 is minimum gain
gain_frac = clamp(gain_frac, 1.0/64, 1.0);
gain_frac = std::clamp(gain_frac, 1.0f/64, 1.0f);
// linearize gain response
// TODO: will be wrong for front camera
@ -442,21 +470,10 @@ static void do_autoexposure(CameraState *s, float grey_frac) {
}
}
void camera_autoexposure(CameraState *s, float grey_frac) {
CameraMsg msg = {
.type = CAMERA_MSG_AUTOEXPOSE,
.camera_num = s->camera_num,
.grey_frac = grey_frac,
};
zmq_send(s->ops_sock_handle, &msg, sizeof(msg), ZMQ_DONTWAIT);
}
static uint8_t* get_eeprom(int eeprom_fd, size_t *out_len) {
int err;
struct msm_eeprom_cfg_data cfg;
memset(&cfg, 0, sizeof(struct msm_eeprom_cfg_data));
struct msm_eeprom_cfg_data cfg = {};
cfg.cfgtype = CFG_EEPROM_GET_CAL_DATA;
err = ioctl(eeprom_fd, VIDIOC_MSM_EEPROM_CFG, &cfg);
assert(err >= 0);
@ -556,8 +573,7 @@ static void sensors_init(MultiCameraState *s) {
}
assert(sensorinit_fd >= 0);
struct sensor_init_cfg_data sensor_init_cfg;
memset(&sensor_init_cfg, 0, sizeof(struct sensor_init_cfg_data));
struct sensor_init_cfg_data sensor_init_cfg = {};
// init rear sensor
@ -1073,31 +1089,17 @@ static void sensors_init(MultiCameraState *s) {
static void camera_open(CameraState *s, bool rear) {
int err;
struct sensorb_cfg_data sensorb_cfg_data;
memset(&sensorb_cfg_data, 0, sizeof(struct sensorb_cfg_data));
struct csid_cfg_data csid_cfg_data;
memset(&csid_cfg_data, 0, sizeof(struct csid_cfg_data));
struct csiphy_cfg_data csiphy_cfg_data;
memset(&csiphy_cfg_data, 0, sizeof(struct csiphy_cfg_data));
struct msm_camera_csiphy_params csiphy_params;
memset(&csiphy_params, 0, sizeof(struct msm_camera_csiphy_params));
struct msm_camera_csid_params csid_params;
memset(&csid_params, 0, sizeof(struct msm_camera_csid_params));
struct msm_vfe_input_cfg input_cfg;
memset(&input_cfg, 0, sizeof(struct msm_vfe_input_cfg));
struct msm_vfe_axi_stream_update_cmd update_cmd;
memset(&update_cmd, 0, sizeof(struct msm_vfe_axi_stream_update_cmd));
struct v4l2_event_subscription sub;
memset(&sub, 0, sizeof(struct v4l2_event_subscription));
struct ispif_cfg_data ispif_cfg_data;
memset(&ispif_cfg_data, 0, sizeof(struct ispif_cfg_data));
struct msm_vfe_cfg_cmd_list cfg_cmd_list;
memset(&cfg_cmd_list, 0, sizeof(struct msm_vfe_cfg_cmd_list));
struct sensorb_cfg_data sensorb_cfg_data = {};
struct csid_cfg_data csid_cfg_data = {};
struct csiphy_cfg_data csiphy_cfg_data = {};
struct msm_camera_csiphy_params csiphy_params = {};
struct msm_camera_csid_params csid_params = {};
struct msm_vfe_input_cfg input_cfg = {};
struct msm_vfe_axi_stream_update_cmd update_cmd = {};
struct v4l2_event_subscription sub = {};
struct msm_actuator_cfg_data actuator_cfg_data;
memset(&actuator_cfg_data, 0, sizeof(struct msm_actuator_cfg_data));
struct msm_ois_cfg_data ois_cfg_data;
memset(&ois_cfg_data, 0, sizeof(struct msm_ois_cfg_data));
struct msm_actuator_cfg_data actuator_cfg_data = {};
struct msm_ois_cfg_data ois_cfg_data = {};
// open devices
const char *sensor_dev;
@ -1717,7 +1719,7 @@ void actuator_move(CameraState *s, uint16_t target) {
}
int dest_step_pos = s->cur_step_pos + step;
dest_step_pos = clamp(dest_step_pos, 0, 255);
dest_step_pos = std::clamp(dest_step_pos, 0, 255);
struct msm_actuator_cfg_data actuator_cfg_data = {0};
actuator_cfg_data.cfgtype = CFG_MOVE_FOCUS;
@ -1803,8 +1805,8 @@ static void do_autofocus(CameraState *s) {
}
// stay off the walls
lens_true_pos = clamp(lens_true_pos, dac_down, dac_up);
int target = clamp(lens_true_pos - sag, dac_down, dac_up);
lens_true_pos = std::clamp(lens_true_pos, float(dac_down), float(dac_up));
int target = std::clamp(lens_true_pos - sag, float(dac_down), float(dac_up));
s->lens_true_pos = lens_true_pos;
/*char debug[4096];
@ -1817,6 +1819,19 @@ static void do_autofocus(CameraState *s) {
actuator_move(s, target);
}
void camera_autoexposure(CameraState *s, float grey_frac) {
if (s->camera_num == 0) {
CameraExpInfo tmp = rear_exp.load();
tmp.op_id++;
tmp.grey_frac = grey_frac;
rear_exp.store(tmp);
} else {
CameraExpInfo tmp = front_exp.load();
tmp.op_id++;
tmp.grey_frac = grey_frac;
front_exp.store(tmp);
}
}
static void front_start(CameraState *s) {
int err;
@ -1827,16 +1842,10 @@ static void front_start(CameraState *s) {
LOG("sensor start regs: %d", err);
}
void cameras_open(MultiCameraState *s, VisionBuf *camera_bufs_rear, VisionBuf *camera_bufs_focus, VisionBuf *camera_bufs_stats, VisionBuf *camera_bufs_front) {
void cameras_open(MultiCameraState *s) {
int err;
struct ispif_cfg_data ispif_cfg_data;
memset(&ispif_cfg_data, 0, sizeof(struct ispif_cfg_data));
struct msm_ispif_param_data ispif_params;
memset(&ispif_params, 0, sizeof(struct msm_ispif_param_data));
struct ispif_cfg_data ispif_cfg_data = {};
struct msm_ispif_param_data ispif_params = {};
ispif_params.num = 4;
// rear camera
ispif_params.entries[0].vfe_intf = VFE0;
@ -1863,9 +1872,6 @@ void cameras_open(MultiCameraState *s, VisionBuf *camera_bufs_rear, VisionBuf *c
ispif_params.entries[3].cids[0] = CID2;
ispif_params.entries[3].csid = CSID0;
assert(camera_bufs_rear);
assert(camera_bufs_front);
s->msmcfg_fd = open("/dev/media0", O_RDWR | O_NONBLOCK);
assert(s->msmcfg_fd >= 0);
@ -1889,13 +1895,13 @@ void cameras_open(MultiCameraState *s, VisionBuf *camera_bufs_rear, VisionBuf *c
// LOG("ispif stop: %d", err);
LOG("*** open front ***");
s->front.ss[0].bufs = camera_bufs_front;
s->front.ss[0].bufs = s->front.buf.camera_bufs.get();
camera_open(&s->front, false);
LOG("*** open rear ***");
s->rear.ss[0].bufs = camera_bufs_rear;
s->rear.ss[1].bufs = camera_bufs_focus;
s->rear.ss[2].bufs = camera_bufs_stats;
s->rear.ss[0].bufs = s->rear.buf.camera_bufs.get();
s->rear.ss[1].bufs = s->focus_bufs;
s->rear.ss[2].bufs = s->stats_bufs;
camera_open(&s->rear, true);
if (getenv("CAMERA_TEST")) {
@ -1936,7 +1942,7 @@ void cameras_open(MultiCameraState *s, VisionBuf *camera_bufs_rear, VisionBuf *c
static void camera_close(CameraState *s) {
int err;
tbuffer_stop(&s->camera_tb);
s->buf.stop();
// ISP: STOP_STREAM
s->stream_cfg.cmd = STOP_STREAM;
@ -1958,8 +1964,6 @@ static void camera_close(CameraState *s) {
}
free(s->eeprom);
zsock_destroy(&s->ops_sock);
}
@ -2006,107 +2010,152 @@ static FrameMetadata get_frame_metadata(CameraState *s, uint32_t frame_id) {
};
}
static void ops_term() {
zsock_t *ops_sock = zsock_new_push(">inproc://cameraops");
assert(ops_sock);
CameraMsg msg = {.type = -1};
zmq_send(zsock_resolve(ops_sock), &msg, sizeof(msg), ZMQ_DONTWAIT);
zsock_destroy(&ops_sock);
}
static void* ops_thread(void* arg) {
int err;
MultiCameraState *s = (MultiCameraState*)arg;
int rear_op_id_last = 0;
int front_op_id_last = 0;
CameraExpInfo rear_op;
CameraExpInfo front_op;
set_thread_name("camera_settings");
zsock_t *cameraops = zsock_new_pull("@inproc://cameraops");
assert(cameraops);
while(!do_exit) {
rear_op = rear_exp.load();
if (rear_op.op_id != rear_op_id_last) {
do_autoexposure(&s->rear, rear_op.grey_frac);
do_autofocus(&s->rear);
rear_op_id_last = rear_op.op_id;
}
zsock_t *terminate = zsock_new_sub(">inproc://terminate", "");
assert(terminate);
front_op = front_exp.load();
if (front_op.op_id != front_op_id_last) {
do_autoexposure(&s->front, front_op.grey_frac);
front_op_id_last = front_op.op_id;
}
zpoller_t *poller = zpoller_new(cameraops, terminate, NULL);
assert(poller);
usleep(50000);
}
SubMaster sm({"sensorEvents"}); // msgq submaster
return NULL;
}
while (!do_exit) {
// zmq handling
zsock_t *which = (zsock_t*)zpoller_wait(poller, -1);
if (which == terminate) {
break;
} else if (which != NULL) {
void* sockraw = zsock_resolve(which);
void camera_process_front(MultiCameraState *s, CameraState *c, int cnt) {
common_camera_process_front(s->sm, s->pm, c, cnt);
}
if (which == cameraops) {
zmq_msg_t msg;
err = zmq_msg_init(&msg);
assert(err == 0);
// called by processing_thread
void camera_process_frame(MultiCameraState *s, CameraState *c, int cnt) {
const CameraBuf *b = &c->buf;
// cache rgb roi and write to cl
err = zmq_msg_recv(&msg, sockraw, 0);
if (err >= 0) {
CameraMsg cmsg;
if (zmq_msg_size(&msg) == sizeof(cmsg)) {
memcpy(&cmsg, zmq_msg_data(&msg), zmq_msg_size(&msg));
//LOGD("cameraops %d", cmsg.type);
if (cmsg.type == CAMERA_MSG_AUTOEXPOSE) {
if (cmsg.camera_num == 0) {
do_autoexposure(&s->rear, cmsg.grey_frac);
do_autofocus(&s->rear);
} else {
do_autoexposure(&s->front, cmsg.grey_frac);
}
} else if (cmsg.type == -1) {
break;
}
}
} else {
// skip if zmq is interrupted by msgq
int err_no = zmq_errno();
assert(err_no == EINTR || err_no == EAGAIN);
// gz compensation
s->sm->update(0);
if (s->sm->updated("sensorEvents")) {
float vals[3] = {0.0};
bool got_accel = false;
auto sensor_events = (*(s->sm))["sensorEvents"].getSensorEvents();
for (auto sensor_event : sensor_events) {
if (sensor_event.which() == cereal::SensorEventData::ACCELERATION) {
auto v = sensor_event.getAcceleration().getV();
if (v.size() < 3) {
continue;
}
zmq_msg_close(&msg);
for (int j = 0; j < 3; j++) {
vals[j] = v[j];
}
got_accel = true;
break;
}
}
// msgq handling
if (sm.update(0) > 0) {
float vals[3] = {0.0};
bool got_accel = false;
auto sensor_events = sm["sensorEvents"].getSensorEvents();
for (auto sensor_event : sensor_events) {
if (sensor_event.which() == cereal::SensorEventData::ACCELERATION) {
auto v = sensor_event.getAcceleration().getV();
if (v.size() < 3) {
continue; //wtf
}
for (int j = 0; j < 3; j++) {
vals[j] = v[j];
}
got_accel = true;
break;
}
}
uint64_t ts = nanos_since_boot();
if (got_accel && ts - s->rear.last_sag_ts > 10000000) { // 10 ms
s->rear.last_sag_ts = ts;
s->rear.last_sag_acc_z = -vals[2];
}
uint64_t ts = nanos_since_boot();
if (got_accel && ts - s->rear.last_sag_ts > 10000000) { // 10 ms
s->rear.last_sag_ts = ts;
s->rear.last_sag_acc_z = -vals[2];
}
}
zpoller_destroy(&poller);
zsock_destroy(&cameraops);
zsock_destroy(&terminate);
// sharpness scores
int roi_id = cnt % ARRAYSIZE(s->lapres); // rolling roi
int roi_x_offset = roi_id % (ROI_X_MAX-ROI_X_MIN+1);
int roi_y_offset = roi_id / (ROI_X_MAX-ROI_X_MIN+1);
return NULL;
for (int r=0;r<(b->rgb_height/NUM_SEGMENTS_Y);r++) {
memcpy(s->rgb_roi_buf.get() + r * (b->rgb_width/NUM_SEGMENTS_X) * 3,
(uint8_t *) b->cur_rgb_buf->addr + \
(ROI_Y_MIN + roi_y_offset) * b->rgb_height/NUM_SEGMENTS_Y * FULL_STRIDE_X * 3 + \
(ROI_X_MIN + roi_x_offset) * b->rgb_width/NUM_SEGMENTS_X * 3 + r * FULL_STRIDE_X * 3,
b->rgb_width/NUM_SEGMENTS_X * 3);
}
assert(clEnqueueWriteBuffer(b->q, s->rgb_conv_roi_cl, true, 0,
b->rgb_width / NUM_SEGMENTS_X * b->rgb_height / NUM_SEGMENTS_Y * 3 * sizeof(uint8_t), s->rgb_roi_buf.get(), 0, 0, 0) == 0);
assert(clSetKernelArg(s->krnl_rgb_laplacian, 0, sizeof(cl_mem), (void *)&s->rgb_conv_roi_cl) == 0);
assert(clSetKernelArg(s->krnl_rgb_laplacian, 1, sizeof(cl_mem), (void *)&s->rgb_conv_result_cl) == 0);
assert(clSetKernelArg(s->krnl_rgb_laplacian, 2, sizeof(cl_mem), (void *)&s->rgb_conv_filter_cl) == 0);
assert(clSetKernelArg(s->krnl_rgb_laplacian, 3, s->conv_cl_localMemSize, 0) == 0);
cl_event conv_event;
assert(clEnqueueNDRangeKernel(b->q, s->krnl_rgb_laplacian, 2, NULL,
s->conv_cl_globalWorkSize, s->conv_cl_localWorkSize, 0, 0, &conv_event) == 0);
clWaitForEvents(1, &conv_event);
clReleaseEvent(conv_event);
assert(clEnqueueReadBuffer(b->q, s->rgb_conv_result_cl, true, 0,
b->rgb_width / NUM_SEGMENTS_X * b->rgb_height / NUM_SEGMENTS_Y * sizeof(int16_t), s->conv_result.get(), 0, 0, 0) == 0);
get_lapmap_one(s->conv_result.get(), &s->lapres[roi_id], b->rgb_width / NUM_SEGMENTS_X, b->rgb_height / NUM_SEGMENTS_Y);
// setup self recover
const float lens_true_pos = s->rear.lens_true_pos;
std::atomic<int>& self_recover = s->rear.self_recover;
if (is_blur(&s->lapres[0]) &&
(lens_true_pos < (s->rear.device == DEVICE_LP3 ? LP3_AF_DAC_DOWN : OP3T_AF_DAC_DOWN) + 1 ||
lens_true_pos > (s->rear.device == DEVICE_LP3 ? LP3_AF_DAC_UP : OP3T_AF_DAC_UP) - 1) &&
self_recover < 2) {
// truly stuck, needs help
self_recover -= 1;
if (self_recover < -FOCUS_RECOVER_PATIENCE) {
LOGD("rear camera bad state detected. attempting recovery from %.1f, recover state is %d",
lens_true_pos, self_recover.load());
self_recover = FOCUS_RECOVER_STEPS + ((lens_true_pos < (s->rear.device == DEVICE_LP3 ? LP3_AF_DAC_M : OP3T_AF_DAC_M)) ? 1 : 0); // parity determined by which end is stuck at
}
} else if ((lens_true_pos < (s->rear.device == DEVICE_LP3 ? LP3_AF_DAC_M - LP3_AF_DAC_3SIG : OP3T_AF_DAC_M - OP3T_AF_DAC_3SIG) ||
lens_true_pos > (s->rear.device == DEVICE_LP3 ? LP3_AF_DAC_M + LP3_AF_DAC_3SIG : OP3T_AF_DAC_M + OP3T_AF_DAC_3SIG)) &&
self_recover < 2) {
// in suboptimal position with high prob, but may still recover by itself
self_recover -= 1;
if (self_recover < -(FOCUS_RECOVER_PATIENCE * 3)) {
self_recover = FOCUS_RECOVER_STEPS / 2 + ((lens_true_pos < (s->rear.device == DEVICE_LP3 ? LP3_AF_DAC_M : OP3T_AF_DAC_M)) ? 1 : 0);
}
} else if (self_recover < 0) {
self_recover += 1; // reset if fine
}
{
MessageBuilder msg;
auto framed = msg.initEvent().initFrame();
fill_frame_data(framed, b->cur_frame_data, cnt);
framed.setFocusVal(kj::ArrayPtr<const int16_t>(&s->rear.focus[0], NUM_FOCUS));
framed.setFocusConf(kj::ArrayPtr<const uint8_t>(&s->rear.confidence[0], NUM_FOCUS));
framed.setSharpnessScore(kj::ArrayPtr<const uint16_t>(&s->lapres[0], ARRAYSIZE(s->lapres)));
framed.setRecoverState(self_recover);
framed.setTransform(kj::ArrayPtr<const float>(&b->yuv_transform.v[0], 9));
s->pm->send("frame", msg);
}
if (cnt % 100 == 3) {
create_thumbnail(s, c, (uint8_t*)b->cur_rgb_buf->addr);
}
const int exposure_x = 290;
const int exposure_y = 322;
const int exposure_width = 560;
const int exposure_height = 314;
const int skip = 1;
if (cnt % 3 == 0) {
set_exposure_target(c, (const uint8_t *)b->yuv_bufs[b->cur_yuv_idx].y, 0, exposure_x, exposure_x + exposure_width, skip, exposure_y, exposure_y + exposure_height, skip);
}
}
void cameras_run(MultiCameraState *s) {
@ -2116,6 +2165,9 @@ void cameras_run(MultiCameraState *s) {
err = pthread_create(&ops_thread_handle, NULL,
ops_thread, s);
assert(err == 0);
std::vector<std::thread> threads;
threads.push_back(start_process_thread(s, "processing", &s->rear, 51, camera_process_frame));
threads.push_back(start_process_thread(s, "frontview", &s->front, 51, camera_process_front));
CameraState* cameras[2] = {&s->rear, &s->front};
@ -2173,8 +2225,8 @@ void cameras_run(MultiCameraState *s) {
//printf("divert: %d %d %d\n", i, buffer, buf_idx);
if (buffer == 0) {
c->camera_bufs_metadata[buf_idx] = get_frame_metadata(c, isp_event_data->frame_id);
tbuffer_dispatch(&c->camera_tb, buf_idx);
c->buf.camera_bufs_metadata[buf_idx] = get_frame_metadata(c, isp_event_data->frame_id);
tbuffer_dispatch(&c->buf.camera_tb, buf_idx);
} else {
uint8_t *d = (uint8_t*)(c->ss[buffer].bufs[buf_idx].addr);
if (buffer == 1) {
@ -2214,14 +2266,27 @@ void cameras_run(MultiCameraState *s) {
LOG(" ************** STOPPING **************");
ops_term();
err = pthread_join(ops_thread_handle, NULL);
assert(err == 0);
cameras_close(s);
for (auto &t : threads) t.join();
}
void cameras_close(MultiCameraState *s) {
camera_close(&s->rear);
camera_close(&s->front);
for (int i = 0; i < FRAME_BUF_COUNT; i++) {
visionbuf_free(&s->focus_bufs[i]);
visionbuf_free(&s->stats_bufs[i]);
}
clReleaseMemObject(s->rgb_conv_roi_cl);
clReleaseMemObject(s->rgb_conv_result_cl);
clReleaseMemObject(s->rgb_conv_filter_cl);
clReleaseProgram(s->prg_rgb_laplacian);
clReleaseKernel(s->krnl_rgb_laplacian);
delete s->sm;
delete s->pm;
}

View File

@ -3,7 +3,7 @@
#include <stdint.h>
#include <stdbool.h>
#include <pthread.h>
#include <czmq.h>
#include <memory>
#include <atomic>
#include "messaging.hpp"
@ -40,10 +40,6 @@
#define FOCUS_RECOVER_PATIENCE 50 // 2.5 seconds of complete blur
#define FOCUS_RECOVER_STEPS 240 // 6 seconds
#ifdef __cplusplus
extern "C" {
#endif
typedef struct CameraState CameraState;
typedef int (*camera_apply_exposure_func)(CameraState *s, int gain, int integ_lines, int frame_length);
@ -59,13 +55,9 @@ typedef struct CameraState {
int camera_num;
int camera_id;
CameraInfo ci;
int frame_size;
int device;
void* ops_sock_handle;
zsock_t * ops_sock;
uint32_t pixel_clock;
uint32_t line_length_pclk;
unsigned int max_gain;
@ -85,8 +77,6 @@ typedef struct CameraState {
uint8_t *eeprom;
// uint32_t camera_bufs_ids[FRAME_BUF_COUNT];
FrameMetadata camera_bufs_metadata[FRAME_BUF_COUNT];
TBuffer camera_tb;
pthread_mutex_t frame_info_lock;
FrameMetadata frame_metadata[METADATA_BUF_COUNT];
@ -121,6 +111,8 @@ typedef struct CameraState {
int fps;
mat3 transform;
CameraBuf buf;
} CameraState;
@ -131,19 +123,35 @@ typedef struct MultiCameraState {
unique_fd msmcfg_fd;
unique_fd v4l_fd;
cl_mem rgb_conv_roi_cl, rgb_conv_result_cl, rgb_conv_filter_cl;
uint16_t lapres[(ROI_X_MAX-ROI_X_MIN+1)*(ROI_Y_MAX-ROI_Y_MIN+1)];
VisionBuf focus_bufs[FRAME_BUF_COUNT];
VisionBuf stats_bufs[FRAME_BUF_COUNT];
cl_program prg_rgb_laplacian;
cl_kernel krnl_rgb_laplacian;
std::unique_ptr<uint8_t[]> rgb_roi_buf;
std::unique_ptr<int16_t[]> conv_result;
int conv_cl_localMemSize;
size_t conv_cl_globalWorkSize[2];
size_t conv_cl_localWorkSize[2];
CameraState rear;
CameraState front;
SubMaster *sm;
PubMaster *pm;
} MultiCameraState;
void cameras_init(MultiCameraState *s);
void cameras_open(MultiCameraState *s, VisionBuf *camera_bufs_rear, VisionBuf *camera_bufs_focus, VisionBuf *camera_bufs_stats, VisionBuf *camera_bufs_front);
void cameras_init(MultiCameraState *s, cl_device_id device_id, cl_context ctx);
void cameras_open(MultiCameraState *s);
void cameras_run(MultiCameraState *s);
void cameras_close(MultiCameraState *s);
void camera_autoexposure(CameraState *s, float grey_frac);
void actuator_move(CameraState *s, uint16_t target);
int sensor_write_regs(CameraState *s, struct msm_camera_i2c_reg_array* arr, size_t size, int data_type);
#ifdef __cplusplus
} // extern "C"
#endif

Some files were not shown because too many files have changed in this diff Show More