Compare commits

..

37 Commits

Author SHA1 Message Date
Vehicle Researcher
1b8c44b506 openpilot v0.3.4 tweaks 2017-07-28 20:51:27 -07:00
Vehicle Researcher
6f46f988d9 openpilot v0.3.4 release 2017-07-28 03:23:57 -07:00
George Hotz
68485aa4e4 Merge pull request #116 from commaai/revert-114-new_panda_code
Revert "Pulled in new panda firmware and updated boardd to support the changes."
2017-07-17 23:17:13 -07:00
George Hotz
1581fdc198 Revert "Pulled in new panda firmware and updated boardd to support the changes." 2017-07-17 23:16:57 -07:00
George Hotz
317ae0fb37 Merge pull request #114 from diamondman/new_panda_code
Pulled in new panda firmware and updated boardd to support the changes.
2017-07-11 22:24:38 -07:00
Jessy Diamond Exum
5bf4196aed Removed unnecessary TODO 2017-07-11 22:01:04 -07:00
Jessy Diamond Exum
38aa03e0f7 Moved boardd loopback config to envvar. 2017-07-11 21:59:03 -07:00
Jessy Diamond Exum
9a9dc3ab23 Pulled in new panda firmware and updated boardd to support the changes. 2017-07-11 21:45:16 -07:00
George Hotz
e4aa959e2c Merge pull request #113 from pjlao307/update-alert-text
Update alert text
2017-07-07 10:25:59 -07:00
Joey Lao
2aa9a56f40 Update steering controls saturated message 2017-07-06 22:36:55 -07:00
pjlao307
721ed4ec0e Merge pull request #2 from commaai/release
Release
2017-07-03 11:15:42 -07:00
George Hotz
70be4ceab1 Merge pull request #109 from commaai/devel
openpilot 0.3.3
2017-06-30 18:23:10 -07:00
Vehicle Researcher
5cf91d0496 openpilot v0.3.3 release 2017-06-28 13:57:09 -07:00
George Hotz
6fee0bdb2d Merge pull request #102 from energee/devel-crv
Bounty: 2016 Honda CR-V Touring
2017-06-22 11:52:38 -07:00
Ted Slesinski
e40c161125 Addresses brake error review comment 2017-06-20 02:51:58 -04:00
Ted Slesinski
97eb55cc55 Fixes global saturation change 2017-06-20 02:47:47 -04:00
Ted Slesinski
65134be0d1 Adds correct value of 8 to gearshifter check array 2017-06-20 02:46:59 -04:00
Ted Slesinski
dbf71a23aa Init crv variable 2017-06-20 02:26:50 -04:00
George Hotz
7fec3db1d6 Merge pull request #103 from pjlao307/pjlao-update-ui
Update UI to make text more readable in all conditions as requested by community
2017-06-19 20:37:37 -07:00
Joey Lao
26b573c1d0 Make lead car text a little brighter 2017-06-12 16:39:10 -07:00
Vehicle Researcher
5ec1e7307e Revert last commit since KPH can get 3 digits long 2017-06-12 09:30:47 -07:00
Vehicle Researcher
8bc36b7f21 Adjust position of left speed to align with label (based on 2 digit speeds) 2017-06-12 09:03:49 -07:00
Vehicle Researcher
3b909eb693 More code cleanup 2017-06-12 08:41:11 -07:00
Vehicle Researcher
57e39c4472 Use color param in ui_draw_rounded_rect instead of hard coding 2017-06-12 08:27:57 -07:00
Vehicle Researcher
ff7672339c Add background to radar text. Code cleanup. 2017-06-12 08:19:47 -07:00
John Jones
6e824a2c22 missed one update in latcontrol 2017-06-11 21:33:44 -04:00
Vehicle Researcher
32fa49e093 Clean up code 2017-06-11 15:18:39 -07:00
Vehicle Researcher
2250eac58f Remove commented line 2017-06-11 15:16:46 -07:00
Vehicle Researcher
97be6b3a0e Update UI to make speed text more readable in all conditions as requested by community 2017-06-11 15:12:50 -07:00
John Jones
942655c947 adding steering change from video and removing integer div and adding ki/kp changes 2017-06-11 13:20:19 -04:00
Ted Slesinski
615db3f7fd Reverting steering to original value 2017-06-08 13:15:30 -04:00
Ted Slesinski
0bb75c5389 Syntax typo 2017-06-08 02:33:31 -04:00
Ted Slesinski
7b5ee81d2d Adds support for 2016 Honda CR-V Touring 2017-06-08 01:37:39 -04:00
Vehicle Researcher
7fe46f1e1d openpilot v0.3.2 release 2017-05-22 22:26:12 -07:00
George Hotz
50c0d1c9da Merge pull request #82 from energee/devel
DBC file for 2017 Honda CR-V
2017-05-22 09:00:44 -07:00
Ted Slesinski
6dbf544d06 Adds 2017 CR-V dbc file 2017-05-21 19:46:34 -04:00
Vehicle Researcher
41e3a0f699 openpilot v0.3.1 release 2017-05-17 00:40:33 -07:00
85 changed files with 2559 additions and 2368 deletions

6
.gitignore vendored
View File

@@ -1,18 +1,22 @@
.DS_Store
.tags
.ipynb_checkpoints
.idea
model2.png
*.d
*.pyc
*.pyo
.*.swp
.*.swo
.*.un~
*.o
*.d
*.so
*.a
*.clb
*.class
*.pyxbldc
*.vcd
config.json
clcache

6
.gitmodules vendored
View File

@@ -1,3 +1,9 @@
[submodule "panda"]
path = panda
url = https://github.com/commaai/panda.git
[submodule "opendbc"]
path = opendbc
url = https://github.com/commaai/opendbc.git
[submodule "pyextra"]
path = pyextra
url = https://github.com/commaai/openpilot-pyextra.git

View File

@@ -1,15 +1,9 @@
FROM ubuntu:14.04
FROM ubuntu:16.04
ENV PYTHONUNBUFFERED 1
RUN apt-get update && apt-get install -y build-essential screen wget bzip2 git libglib2.0-0
RUN apt-get update && apt-get install -y build-essential clang vim screen wget bzip2 git libglib2.0-0 python-pip capnproto libcapnp-dev libzmq5-dev libffi-dev
RUN wget -nv -O /tmp/anaconda.sh https://repo.continuum.io/archive/Anaconda2-4.2.0-Linux-x86_64.sh && \
/bin/bash /tmp/anaconda.sh -b -p /opt/conda && \
rm /tmp/anaconda.sh
ENV PATH /opt/conda/bin:$PATH
RUN conda install numpy==1.11.2 && conda install scipy==0.18.1
RUN pip install numpy==1.11.2 scipy==0.18.1 matplotlib
COPY requirements_openpilot.txt /tmp/
RUN pip install -r /tmp/requirements_openpilot.txt

View File

@@ -7,6 +7,8 @@ Currently it performs the functions of Adaptive Cruise Control (ACC) and Lane Ke
The openpilot codebase has been written to be concise and enable rapid prototyping. We look forward to your contributions - improving real vehicle automation has never been easier.
Here are [some](https://www.youtube.com/watch?v=9OwTJFuDI7g) [videos](https://www.youtube.com/watch?v=64Wvt5pYQmE) [of](https://www.youtube.com/watch?v=6IW7Nejsr3A) [it](https://www.youtube.com/watch?v=-VN1YcC83nA) [running](https://www.youtube.com/watch?v=EQJZvVeihZk). And a really cool [tutorial](https://www.youtube.com/watch?v=PwOnsT2UW5o).
Hardware
------
@@ -18,17 +20,20 @@ Supported Cars
------
- Acura ILX 2016 with AcuraWatch Plus
- Limitations: Due to use of the cruise control for gas, it can only be enabled above 25 mph
- Due to use of the cruise control for gas, it can only be enabled above 25 mph
- Honda Civic 2016 with Honda Sensing
- Limitations: Due to limitations in steering firmware, steering is disabled below 18 mph
- Due to limitations in steering firmware, steering is disabled below 12 mph
- Honda CR-V Touring 2015-2016 (very alpha!)
- Can only be enabled above 25 mph
Directory structure
------
- cereal -- The messaging spec used for all logs on the phone
- common -- Library like functionality we've developed here
- dbcs -- Files showing how to interpret data from cars
- opendbc -- Files showing how to interpret data from cars
- panda -- Code used to communicate on CAN and LIN
- phonelibs -- Libraries used on the phone
- selfdrive -- Code needed to drive the car
@@ -66,11 +71,9 @@ More extensive testing infrastructure and simulation environments are coming soo
Adding Car Support
------
It should be relatively easy to add support for the Honda CR-V Touring. The brake message is the same. Steering has a slightly different message with a different message id. Sniff CAN while using LKAS to find it.
comma.ai offers [bounties](http://comma.ai/bounties.html) for adding additional car support.
The Honda Accord uses different signaling for the steering and probably requires new hardware.
Adding other manufacturers besides Honda/Acura is doable but will be more of an undertaking.
CR-V Touring support came in through this program. Chevy Volt is close. Accord is close as well.
User Data / chffr Account / Crash Reporting
------
@@ -91,13 +94,15 @@ We welcome both pull requests and issues on
[github](http://github.com/commaai/openpilot). See the TODO file for a list of
good places to start.
Want to get paid to work on openpilot? [comma.ai is hiring](http://comma.ai/hiring.html)
Want to get paid to work on openpilot? [comma.ai is hiring](http://comma.ai/positions.html)
Licensing
------
openpilot is released under the MIT license.
Any user of this software shall indemnify and hold harmless Comma.ai, Inc. and its directors, officers, employees, agents, stockholders, affiliates, subcontractors and customers from and against all allegations, claims, actions, suits, demands, damages, liabilities, obligations, losses, settlements, judgments, costs and expenses (including without limitation attorneys fees and costs) which arise out of, relate to or result from any use of this software by user.
**THIS IS ALPHA QUALITY SOFTWARE FOR RESEARCH PURPOSES ONLY. THIS IS NOT A PRODUCT.
YOU ARE RESPONSIBLE FOR COMPLYING WITH LOCAL LAWS AND REGULATIONS.
NO WARRANTY EXPRESSED OR IMPLIED.**

View File

@@ -1,4 +1,34 @@
Version 0.3.0 (2017-03-xx)
Version 0.3.4 (2017-07-28)
==========================
* Improved model trained on more data
* Much improved controls tuning
* Performance improvements
* Bugfixes and improvements to calibration
* Driving log can play back video
* Acura only: system now stays engaged below 25mph as long as brakes are applied
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
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
Version 0.3.1 (2017-05-17)
===========================
* 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

Binary file not shown.

View File

@@ -1,8 +1,20 @@
import os
import capnp
capnp.remove_import_hook()
CEREAL_PATH = os.path.dirname(os.path.abspath(__file__))
log = capnp.load(os.path.join(CEREAL_PATH, "log.capnp"))
car = capnp.load(os.path.join(CEREAL_PATH, "car.capnp"))
capnp.remove_import_hook()
if os.getenv("NEWCAPNP"):
import tempfile
import pyximport
importers = pyximport.install(build_dir=os.path.join(tempfile.gettempdir(), ".pyxbld"))
try:
import cereal.gen.cython.log_capnp_cython as log
import cereal.gen.cython.car_capnp_cython as car
finally:
pyximport.uninstall(*importers)
del importers
else:
log = capnp.load(os.path.join(CEREAL_PATH, "log.capnp"))
car = capnp.load(os.path.join(CEREAL_PATH, "car.capnp"))

View File

@@ -1,14 +1,21 @@
SRCS := log.capnp car.capnp
GENS := gen/c/car.capnp.c gen/c/log.capnp.c gen/c/c++.capnp.h gen/c/java.capnp.h \
gen/cpp/car.capnp.c++ gen/cpp/log.capnp.c++
GENS := gen/cpp/car.capnp.c++ gen/cpp/log.capnp.c++
UNAME_M := $(shell uname -m)
# only generate C++ for docker tests
ifneq ($(OPTEST),1)
GENS += gen/c/car.capnp.c gen/c/log.capnp.c gen/c/c++.capnp.h gen/c/java.capnp.h
# Dont build java on the phone...
UNAME_M := $(shell uname -m)
ifeq ($(UNAME_M),x86_64)
GENS += gen/java/Car.java gen/java/Log.java
endif
endif
.PHONY: all
all: $(GENS)

View File

@@ -50,6 +50,7 @@ struct CarState {
struct CruiseState {
enabled @0: Bool;
speed @1: Float32;
available @2: Bool;
}
enum Error {
@@ -63,7 +64,7 @@ struct CarState {
seatbeltNotLatched @6;
espDisabled @7;
wrongCarMode @8;
steerTemporarilyUnavailable @9;
steerTempUnavailable @9;
reverseGear @10;
# ...
}

View File

@@ -31,6 +31,10 @@ struct InitData {
androidSensors @6 :List(AndroidSensor);
chffrAndroidExtra @7 :ChffrAndroidExtra;
pandaInfo @8 :PandaInfo;
dirty @9 :Bool;
enum DeviceType {
unknown @0;
neo @1;
@@ -84,6 +88,13 @@ struct InitData {
struct ChffrAndroidExtra {
allCameraCharacteristics @0 :Map(Text, Text);
}
struct PandaInfo {
hasPanda @0: Bool;
dongleId @1: Text;
stVersion @2: Text;
espVersion @3: Text;
}
}
struct FrameData {
@@ -129,11 +140,16 @@ struct SensorEventData {
sensor @1 :Int32;
type @2 :Int32;
timestamp @3 :Int64;
uncalibratedDEPRECATED @10 :Bool;
union {
acceleration @4 :SensorVec;
magnetic @5 :SensorVec;
orientation @6 :SensorVec;
gyro @7 :SensorVec;
pressure @9 :SensorVec;
magneticUncalibrated @11 :SensorVec;
gyroUncalibrated @12 :SensorVec;
}
source @8 :SensorSource;
@@ -170,7 +186,7 @@ struct GpsLocationData {
# Represents heading in degrees.
bearing @5 :Float32;
# Represents expected accuracy in meters.
# Represents expected accuracy in meters. (presumably 1 sigma?)
accuracy @6 :Float32;
# Timestamp for the location fix.
@@ -178,6 +194,18 @@ struct GpsLocationData {
timestamp @7 :Int64;
source @8 :SensorSource;
# Represents NED velocity in m/s.
vNED @9 :List(Float32);
# Represents expected vertical accuracy in meters. (presumably 1 sigma?)
verticalAccuracy @10 :Float32;
# Represents bearing accuracy in degrees. (presumably 1 sigma?)
bearingAccuracy @11 :Float32;
# Represents velocity accuracy in m/s. (presumably 1 sigma?)
speedAccuracy @12 :Float32;
enum SensorSource {
android @0;
@@ -186,6 +214,7 @@ struct GpsLocationData {
velodyne @3; # Velodyne IMU
fusion @4;
external @5;
ublox @6;
}
}
@@ -193,7 +222,7 @@ struct CanData {
address @0 :UInt32;
busTime @1 :UInt16;
dat @2 :Data;
src @3 :Int8;
src @3 :UInt8;
}
struct ThermalData {
@@ -231,7 +260,8 @@ struct LiveUI {
struct Live20Data {
canMonoTimes @10 :List(UInt64);
mdMonoTime @6 :UInt64;
ftMonoTime @7 :UInt64;
ftMonoTimeDEPRECATED @7 :UInt64;
l100MonoTime @11 :UInt64;
# all deprecated
warpMatrixDEPRECATED @0 :List(Float32);
@@ -284,10 +314,11 @@ struct LiveTracks {
}
struct Live100Data {
canMonoTime @16 :UInt64;
canMonoTimeDEPRECATED @16 :UInt64;
canMonoTimes @21 :List(UInt64);
l20MonoTime @17 :UInt64;
mdMonoTime @18 :UInt64;
l20MonoTimeDEPRECATED @17 :UInt64;
mdMonoTimeDEPRECATED @18 :UInt64;
planMonoTime @28 :UInt64;
vEgo @0 :Float32;
aEgoDEPRECATED @1 :Float32;
@@ -315,6 +346,8 @@ struct Live100Data {
alertText1 @24 :Text;
alertText2 @25 :Text;
awarenessStatus @26 :Float32;
angleOffset @27 :Float32;
}
struct LiveEventData {
@@ -379,7 +412,8 @@ struct EncodeIndex {
bigBoxLossless @0; # rcamera.mkv
fullHEVC @1; # fcamera.hevc
bigBoxHEVC @2; # bcamera.hevc
chffrAndroidH264 @3; # camera
chffrAndroidH264 @3; # acamera
fullLosslessClip @4; # prcamera.mkv
}
}
@@ -399,6 +433,9 @@ struct LogRotate {
}
struct Plan {
mdMonoTime @9 :UInt64;
l20MonoTime @10 :UInt64;
# lateral, 3rd order polynomial
lateralValid @0: Bool;
dPoly @1 :List(Float32);
@@ -409,6 +446,8 @@ struct Plan {
aTargetMin @4 :Float32;
aTargetMax @5 :Float32;
jerkFactor @6 :Float32;
hasLead @7 :Bool;
fcw @8 :Bool;
}
struct LiveLocationData {
@@ -894,6 +933,114 @@ struct ProcLog {
}
struct UbloxGnss {
union {
measurementReport @0 :MeasurementReport;
ephemeris @1 :Ephemeris;
}
struct MeasurementReport {
#received time of week in gps time in seconds and gps week
rcvTow @0 :Float64;
gpsWeek @1 :UInt16;
# leap seconds in seconds
leapSeconds @2 :UInt16;
# receiver status
receiverStatus @3 :ReceiverStatus;
# num of measurements to follow
numMeas @4 :UInt8;
measurements @5 :List(Measurement);
struct ReceiverStatus {
# leap seconds have been determined
leapSecValid @0 :Bool;
# Clock reset applied
clkReset @1 : Bool;
}
struct Measurement {
svId @0 :UInt8;
trackingStatus @1 :TrackingStatus;
# pseudorange in meters
pseudorange @2 :Float64;
# carrier phase measurement in cycles
carrierCycles @3 :Float64;
# doppler measurement in Hz
doppler @4 :Float32;
# GNSS id, 0 is gps
gnssId @5 :UInt8;
glonassFrequencyIndex @6 :UInt8;
# carrier phase locktime counter in ms
locktime @7 :UInt16;
# Carrier-to-noise density ratio (signal strength) in dBHz
cno @8 : UInt8;
# pseudorange standard deviation in meters
pseudorangeStdev @9 :Float32;
# carrier phase standard deviation in cycles
carrierPhaseStdev @10 :Float32;
# doppler standard deviation in Hz
dopplerStdev @11 :Float32;
struct TrackingStatus {
# pseudorange valid
pseudorangeValid @0 :Bool;
# carrier phase valid
carrierPhaseValid @1 :Bool;
# half cycle valid
halfCycleValid @2 :Bool;
# half sycle subtracted from phase
halfCycleSubtracted @3 :Bool;
}
}
}
struct Ephemeris {
# This is according to the rinex (2?) format
svId @0 :UInt16;
year @1 :UInt16;
month @2 :UInt16;
day @3 :UInt16;
hour @4 :UInt16;
minute @5 :UInt16;
second @6 :Float32;
af0 @7 :Float64;
af1 @8 :Float64;
af2 @9 :Float64;
iode @10 :Float64;
crs @11 :Float64;
deltaN @12 :Float64;
m0 @13 :Float64;
cuc @14 :Float64;
ecc @15 :Float64;
cus @16 :Float64;
a @17 :Float64; # note that this is not the root!!
toe @18 :Float64;
cic @19 :Float64;
omega0 @20 :Float64;
cis @21 :Float64;
i0 @22 :Float64;
crc @23 :Float64;
omega @24 :Float64;
omegaDot @25 :Float64;
iDot @26 :Float64;
codesL2 @27 :Float64;
gpsWeek @28 :Float64;
l2 @29 :Float64;
svAcc @30 :Float64;
svHealth @31 :Float64;
tgd @32 :Float64;
iodc @33 :Float64;
transmissionTime @34 :Float64;
fitInterval @35 :Float64;
}
}
struct Event {
# in nanoseconds?
logMonoTime @0 :UInt64;
@@ -932,5 +1079,6 @@ struct Event {
qcomGnss @31 :QcomGnss;
lidarPts @32 :LidarPts;
procLog @33 :ProcLog;
ubloxGnss @34 :UbloxGnss;
}
}

View File

@@ -1,13 +1,15 @@
import requests
from selfdrive.version import version
def api_get(endpoint, method='GET', timeout=None, access_token=None, **params):
backend = "https://api.commadotai.com/"
params['_version'] = "OPENPILOTv0.3"
headers = {}
if access_token is not None:
headers['Authorization'] = "JWT "+access_token
headers['User-Agent'] = "openpilot-" + version
return requests.request(method, backend+endpoint, timeout=timeout, headers = headers, params=params)

View File

@@ -1,6 +1,7 @@
import re
import os
import struct
import bitstring
from binascii import hexlify
from collections import namedtuple
def int_or_float(s):
@@ -16,6 +17,7 @@ DBCSignal = namedtuple(
class dbc(object):
def __init__(self, fn):
self.name, _ = os.path.splitext(os.path.basename(fn))
with open(fn) as f:
self.txt = f.read().split("\n")
self._warned_addresses = set()
@@ -32,10 +34,8 @@ class dbc(object):
# signals is a list of DBCSignal in order of increasing start_bit.
self.msgs = {}
self.bits = []
for i in range(0, 64, 8):
for j in range(7, -1, -1):
self.bits.append(i+j)
# lookup to bit reverse each byte
self.bits_index = [(i & ~0b111) + ((-i-1) & 0b111) for i in xrange(64)]
for l in self.txt:
l = l.strip()
@@ -102,7 +102,7 @@ class dbc(object):
if s.is_little_endian:
ss = s.start_bit
else:
ss = self.bits.index(s.start_bit)
ss = self.bits_index[s.start_bit]
if s.is_signed:
@@ -135,9 +135,6 @@ class dbc(object):
Returns (None, None) if the message could not be decoded.
"""
def swap_order(d, wsz=4, gsz=2 ):
return "".join(["".join([m[i:i+gsz] for i in range(wsz-gsz,-gsz,-gsz)]) for m in [d[i:i+wsz] for i in range(0,len(d),wsz)]])
if arr is None:
out = {}
else:
@@ -156,6 +153,9 @@ class dbc(object):
blen = 8*len(x[2])
st = x[2].rjust(8, '\x00')
le, be = None, None
for s in msg[1]:
if arr is not None and s[0] not in arr:
continue
@@ -163,15 +163,18 @@ class dbc(object):
# big or little endian?
# see http://vi-firmware.openxcplatform.com/en/master/config/bit-numbering.html
if s[3] is False:
ss = self.bits.index(s[1])
x2_int = int(hexlify(x[2]), 16)
ss = self.bits_index[s[1]]
if be is None:
be = struct.unpack(">Q", st)[0]
x2_int = be
data_bit_pos = (blen - (ss + s[2]))
else:
x2_int = int(swap_order(hexlify(x[2]), 16, 2), 16)
if le is None:
le = struct.unpack("<Q", st)[0]
x2_int = le
ss = s[1]
data_bit_pos = ss
if data_bit_pos < 0:
continue
ival = (x2_int >> data_bit_pos) & ((1 << (s[2])) - 1)

View File

@@ -1,3 +1,4 @@
import os
_FINGERPRINTS = {
"ACURA ILX 2016 ACURAWATCH PLUS": {
@@ -12,6 +13,11 @@ _FINGERPRINTS = {
},
"HONDA ACCORD 2016 TOURING": {
1024L: 5, 929L: 8, 1027L: 5, 773L: 7, 1601L: 8, 777L: 8, 1036L: 8, 398L: 3, 1039L: 8, 401L: 8, 145L: 8, 1424L: 5, 660L: 8, 661L: 4, 918L: 7, 985L: 3, 923L: 2, 542L: 7, 927L: 8, 800L: 8, 545L: 4, 420L: 8, 422L: 8, 808L: 8, 426L: 8, 1029L: 8, 432L: 7, 57L: 3, 316L: 8, 829L: 5, 1600L: 5, 1089L: 8, 1057L: 5, 780L: 8, 1088L: 8, 464L: 8, 1108L: 8, 597L: 8, 342L: 6, 983L: 8, 344L: 8, 804L: 8, 476L: 4, 1296L: 3, 891L: 8, 1125L: 8, 487L: 4, 892L: 8, 490L: 8, 871L: 8, 1064L: 7, 882L: 2, 884L: 8, 506L: 8, 507L: 1, 380L: 8, 1365L: 5
},
"HONDA CR-V 2016 TOURING": {
57L: 3, 145L: 8, 316L: 8, 340L: 8, 342L: 6, 344L: 8, 380L: 8, 398L: 3, 399L: 6, 401L: 8, 420L: 8, 422L: 8, 426L: 8, 432L: 7, 464L: 8, 474L: 5, 476L: 4, 487L: 4, 490L: 8, 493L: 3, 507L: 1, 542L: 7, 545L: 4, 597L: 8, 660L: 8, 661L: 4, 773L: 7, 777L: 8, 800L: 8, 804L: 8, 808L: 8, 882L: 2, 884L: 7, 888L: 8, 891L: 8, 892L: 8, 923L: 2, 929L: 8, 983L: 8, 985L: 3, 1024L: 5, 1027L: 5, 1029L: 8, 1033L: 5, 1036L: 8, 1039L: 8, 1057L: 5, 1064L: 7, 1108L: 8, 1125L: 8, 1296L: 8, 1365L: 5, 1424L: 5, 1600L: 5, 1601L: 8,
# sent messages
0x194: 4, 0x1fa: 8, 0x30c: 8, 0x33d: 5,
}
}
@@ -46,30 +52,13 @@ def fingerprint(logcan):
import selfdrive.messaging as messaging
from cereal import car
from common.realtime import sec_since_boot
import os
if os.getenv("SIMULATOR") is not None or logcan is None:
# send message
ret = car.CarParams.new_message()
ret.carName = "simulator"
ret.radarName = "nidec"
ret.carFingerprint = "THE LOW QUALITY SIMULATOR"
ret.enableSteer = True
ret.enableBrake = True
ret.enableGas = True
ret.enableCruise = False
ret.wheelBase = 2.67
ret.steerRatio = 15.3
ret.slipFactor = 0.0014
ret.steerKp, ret.steerKi = 12.0, 1.0
return ret
return ("simulator", None)
elif os.getenv("SIMULATOR2") is not None:
return ("simulator2", None)
print "waiting for fingerprint..."
brake_only = True
candidate_cars = all_known_cars()
finger = {}
st = None
@@ -78,9 +67,6 @@ def fingerprint(logcan):
if st is None:
st = sec_since_boot()
for can in a.can:
# pedal
if can.address == 0x201 and can.src == 0:
brake_only = False
if can.src == 0:
finger[can.address] = len(can.dat)
candidate_cars = eliminate_incompatible_cars(can, candidate_cars)
@@ -93,36 +79,4 @@ def fingerprint(logcan):
raise Exception("car doesn't match any fingerprints")
print "fingerprinted", candidate_cars[0]
# send message
ret = car.CarParams.new_message()
ret.carName = "honda"
ret.radarName = "nidec"
ret.carFingerprint = candidate_cars[0]
ret.enableSteer = True
ret.enableBrake = True
ret.enableGas = not brake_only
ret.enableCruise = brake_only
#ret.enableCruise = False
ret.wheelBase = 2.67
ret.steerRatio = 15.3
ret.slipFactor = 0.0014
if candidate_cars[0] == "HONDA CIVIC 2016 TOURING":
ret.steerKp, ret.steerKi = 12.0, 1.0
elif candidate_cars[0] == "ACURA ILX 2016 ACURAWATCH PLUS":
if not brake_only:
# assuming if we have an interceptor we also have a torque mod
ret.steerKp, ret.steerKi = 6.0, 0.5
else:
ret.steerKp, ret.steerKi = 12.0, 1.0
elif candidate_cars[0] == "HONDA ACCORD 2016 TOURING":
ret.steerKp, ret.steerKi = 12.0, 1.0
else:
raise ValueError("unsupported car %s" % candidate_cars[0])
return ret
return (candidate_cars[0], finger)

View File

@@ -1,7 +1,6 @@
import abc
import numpy as np
import numpy.matlib
# The EKF class contains the framework for an Extended Kalman Filter, but must be subclassed to use.
# A subclass must implement:
# 1) calc_transfer_fun(); see bottom of file for more info.
@@ -68,55 +67,6 @@ class SimpleSensor:
self.covar = covar
return SensorReading(data, self.covar, self.obs_model)
class GPS:
earth_r = 6371e3 # m, average earth radius
def __init__(self, xy_idx=(0, 1), dims=2, var=1e4):
self.obs_model = np.matlib.zeros((2, dims))
self.obs_model[:, tuple(xy_idx)] = np.matlib.identity(2)
self.covar = np.matlib.identity(2) * var
# [lat, lon] in decimal degrees
def init_pos(self, latlon):
self.init_lat, self.init_lon = np.radians(np.asarray(latlon[:2]))
# Compute straight-line distance, in meters, between two lat/long coordinates
# Input in radians
def haversine(self, lat1, lon1, lat2, lon2):
lat_diff = lat2 - lat1
lon_diff = lon2 - lon1
d = np.sin(lat_diff * 0.5)**2 + np.cos(lat1) * np.cos(lat2) * np.sin(
lon_diff * 0.5)**2
h = 2 * GPS.earth_r * np.arcsin(np.sqrt(d))
return h
# Convert decimal degrees into meters
def convert_deg2m(self, lat, lon):
lat, lon = np.radians([lat, lon])
xs = (lon - self.init_lon) * np.cos(self.init_lat) * GPS.earth_r
ys = (lat - self.init_lat) * GPS.earth_r
return xs, ys
# Convert meters into decimal degrees
def convert_m2deg(self, xs, ys):
lat = ys / GPS.earth_r + self.init_lat
lon = xs / (GPS.earth_r * np.cos(self.init_lat)) + self.init_lon
return np.degrees(lat), np.degrees(lon)
# latlon is [lat, long,] as decimal degrees
# accuracy is as given by Android location service: radius of 68% confidence
def read(self, latlon, accuracy=None):
x_dist, y_dist = self.convert_deg2m(latlon[0], latlon[1])
if not accuracy:
covar = self.covar
else:
covar = np.matlib.identity(2) * accuracy**2
return SensorReading(
np.asmatrix([x_dist, y_dist]).T, covar, self.obs_model)
class EKF:
__metaclass__ = abc.ABCMeta
@@ -224,7 +174,7 @@ class EKF:
#! Clip covariance to avoid explosions
self.covar = np.clip(self.covar,-1e10,1e10)
@abc.abstractmethod
def calc_transfer_fun(self, dt):
"""Return a tuple with the transfer function and transfer function jacobian

View File

@@ -8,6 +8,18 @@ from threading import local
from collections import OrderedDict
from contextlib import contextmanager
def json_handler(obj):
# if isinstance(obj, (datetime.date, datetime.time)):
# return obj.isoformat()
return repr(obj)
def json_robust_dumps(obj):
return json.dumps(obj, default=json_handler)
class NiceOrderedDict(OrderedDict):
def __str__(self):
return '{'+', '.join("%r: %r" % p for p in self.iteritems())+'}'
class SwagFormatter(logging.Formatter):
def __init__(self, swaglogger):
logging.Formatter.__init__(self, None, '%a %b %d %H:%M:%S %Z %Y')
@@ -15,13 +27,8 @@ class SwagFormatter(logging.Formatter):
self.swaglogger = swaglogger
self.host = socket.gethostname()
def json_handler(self, obj):
# if isinstance(obj, (datetime.date, datetime.time)):
# return obj.isoformat()
return repr(obj)
def format(self, record):
record_dict = OrderedDict()
def format_dict(self, record):
record_dict = NiceOrderedDict()
if isinstance(record.msg, dict):
record_dict['msg'] = record.msg
@@ -50,9 +57,10 @@ class SwagFormatter(logging.Formatter):
record_dict['threadName'] = record.threadName
record_dict['created'] = record.created
# asctime = self.formatTime(record, self.datefmt)
return record_dict
return json.dumps(record_dict, default=self.json_handler)
def format(self, record):
return json_robust_dumps(self.format_dict(record))
_tmpfunc = lambda: 0
_srcfile = os.path.normcase(_tmpfunc.__code__.co_filename)
@@ -115,7 +123,7 @@ class SwagLogger(logging.Logger):
self.global_ctx.update(kwargs)
def event(self, event_name, *args, **kwargs):
evt = OrderedDict()
evt = NiceOrderedDict()
evt['event'] = event_name
if args:
evt['args'] = args

View File

@@ -52,6 +52,10 @@ keys = {
"Version": TxType.PERSISTANT,
"GitCommit": TxType.PERSISTANT,
"GitBranch": TxType.PERSISTANT,
# written: baseui
# read: ui, controls
"IsMetric": TxType.PERSISTANT,
"IsRearViewMirror": TxType.PERSISTANT,
# written: visiond
# read: visiond
"CalibrationParams": TxType.PERSISTANT,

View File

@@ -1,43 +1,53 @@
"""Utilities for reading real time clocks and keeping soft real time constraints."""
import os
import time
import ctypes
import platform
import threading
import subprocess
import multiprocessing
import os
from ctypes.util import find_library
from cffi import FFI
ffi = FFI()
ffi.cdef("""
typedef int clockid_t;
struct timespec {
long tv_sec; /* Seconds. */
long tv_nsec; /* Nanoseconds. */
};
int clock_gettime (clockid_t clk_id, struct timespec *tp);
long syscall(long number, ...);
"""
)
libc = ffi.dlopen(None)
CLOCK_MONOTONIC_RAW = 4 # see <linux/time.h>
# see <linux/time.h>
CLOCK_MONOTONIC_RAW = 4
CLOCK_BOOTTIME = 7
class timespec(ctypes.Structure):
_fields_ = [
('tv_sec', ctypes.c_long),
('tv_nsec', ctypes.c_long),
]
if platform.system() != 'Darwin' and hasattr(libc, 'clock_gettime'):
c_clock_gettime = libc.clock_gettime
libc_name = find_library('c')
libc = ctypes.CDLL(libc_name, use_errno=True)
tlocal = threading.local()
def clock_gettime(clk_id):
if not hasattr(tlocal, 'ts'):
tlocal.ts = ffi.new('struct timespec *')
if hasattr(libc, 'clock_gettime'):
libc.clock_gettime.argtypes = [ctypes.c_int, ctypes.POINTER(timespec)]
has_clock_gettime = True
ts = tlocal.ts
r = c_clock_gettime(clk_id, ts)
if r != 0:
raise OSError("clock_gettime")
return ts.tv_sec + ts.tv_nsec * 1e-9
else:
has_clock_gettime = False
def clock_gettime(clk_id):
if not has_clock_gettime:
# hack. only for OS X < 10.12
# hack. only for OS X < 10.12
def clock_gettime(clk_id):
return time.time()
t = timespec()
if libc.clock_gettime(clk_id, ctypes.pointer(t)) != 0:
errno_ = ctypes.get_errno()
raise OSError(errno_, os.strerror(errno_))
return t.tv_sec + t.tv_nsec * 1e-9
def monotonic_time():
return clock_gettime(CLOCK_MONOTONIC_RAW)
@@ -96,3 +106,6 @@ class Ratekeeper(object):
self._frame += 1
self._remaining = remaining
return lagged
if __name__ == "__main__":
print sec_since_boot()

9
common/testing.py Normal file
View File

@@ -0,0 +1,9 @@
import os
from nose.tools import nottest
def phone_only(x):
if os.path.isfile("/init.qcom.rc"):
return x
else:
return nottest(x)

View File

@@ -1,2 +0,0 @@
import os
DBC_PATH = os.path.dirname(os.path.abspath(__file__))

View File

@@ -1,324 +0,0 @@
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_
BS_:
BU_: INTERCEPTOR EBCM NEO ADAS PCM EPS VSA SCM BDY XXX
BO_ 57 XXX_1: 3 XXX
BO_ 145 XXX_2: 8 XXX
SG_ LAT_ACCEL : 7|10@0+ (0.02,-512) [-20|20] "m/s2" NEO
BO_ 228 STEERING_CONTROL: 5 ADAS
SG_ STEER_TORQUE : 7|16@0- (1,0) [-3840|3840] "" EPS
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 : 31|8@0+ (1,0) [0|0] "" EPS
SG_ COUNTER : 37|2@0+ (1,0) [0|3] "" EPS
SG_ CHECKSUM : 35|4@0+ (1,0) [0|3] "" EPS
BO_ 304 GAS_PEDAL2: 8 PCM
SG_ ENGINE_TORQUE_ESTIMATE : 7|16@0- (1,0) [-1000|1000] "Nm" NEO
SG_ ENGINE_TORQUE_REQUEST : 23|16@0- (1,0) [-1000|1000] "Nm" NEO
SG_ CAR_GAS : 39|8@0+ (1,0) [0|255] "" NEO
BO_ 316 GAS_PEDAL: 8 PCM
SG_ CAR_GAS : 39|8@0+ (1,0) [0|255] "" NEO
BO_ 342 STEERING_SENSORS: 6 EPS
SG_ STEER_ANGLE : 7|16@0- (-0.1,0) [-500|500] "deg" NEO
SG_ STEER_ANGLE_RATE : 23|16@0- (1,0) [-3000|3000] "deg/s" NEO
SG_ COUNTER : 45|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 43|4@0+ (1,0) [0|3] "" NEO
BO_ 344 POWERTRAIN_DATA: 8 PCM
SG_ XMISSION_SPEED : 7|16@0+ (0.002759506,0) [0|70] "m/s" NEO
SG_ ENGINE_RPM : 23|16@0+ (1,0) [0|15000] "rpm" NEO
SG_ XMISSION_SPEED2 : 39|16@0+ (0.002759506,0) [0|70] "m/s" NEO
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" NEO
BO_ 380 POWERTRAIN_DATA2: 8 PCM
SG_ PEDAL_GAS : 7|8@0+ (1,0) [0|255] "" NEO
SG_ ENGINE_RPM : 23|16@0+ (1,0) [0|15000] "rpm" NEO
SG_ GAS_PRESSED : 39|1@0+ (1,0) [0|1] "" NEO
SG_ ACC_STATUS : 38|1@0+ (1,0) [0|1] "rpm" NEO
SG_ BOH_17C : 37|5@0+ (1,0) [0|1] "rpm" NEO
SG_ BRAKE_LIGHTS_ON : 32|1@0+ (1,0) [0|1] "rpm" NEO
SG_ BOH2_17C : 47|10@0+ (1,0) [0|1] "rpm" NEO
SG_ BRAKE_PRESSED : 53|1@0+ (1,0) [0|1] "" NEO
SG_ BOH3_17C : 52|5@0+ (1,0) [0|1] "rpm" NEO
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" NEO
BO_ 398 XXX_3: 3 XXX
BO_ 399 STEER_STATUS: 7 EPS
SG_ STEER_TORQUE_SENSOR : 7|16@0- (1,0) [-31000|31000] "tbd" NEO
SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" NEO
SG_ STEER_STATUS : 39|4@0+ (1,0) [0|15] "" NEO
SG_ STEER_CONTROL_ACTIVE : 35|1@0+ (1,0) [0|1] "" NEO
SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 51|4@0+ (1,0) [0|3] "" NEO
BO_ 419 GEARBOX: 8 PCM
SG_ GEAR : 7|8@0+ (1,0) [0|256] "" NEO
SG_ GEAR_SHIFTER : 35|4@0+ (1,0) [0|15] "" NEO
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" NEO
BO_ 420 VSA_STATUS: 8 VSA
SG_ USER_BRAKE : 7|16@0+ (0.015625,-1.609375) [0|1000] "" NEO
SG_ ESP_DISABLED : 28|1@0+ (1,0) [0|1] "" NEO
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" NEO
BO_ 422 SCM_BUTTONS: 8 SCM
SG_ CRUISE_BUTTONS : 7|3@0+ (1,0) [0|7] "" NEO
SG_ LIGHTS_SETTING : 1|2@0+ (1,0) [0|3] "" NEO
SG_ MAIN_ON : 47|1@0+ (1,0) [0|1] "" NEO
SG_ CRUISE_SETTING : 43|2@0+ (1,0) [0|3] "" NEO
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" NEO
BO_ 428 XXX_4: 8 XXX
BO_ 432 STANDSTILL: 7 VSA
SG_ WHEELS_MOVING : 12|1@0+ (1,0) [0|1] "" NEO
SG_ BRAKE_ERROR_1 : 11|1@0+ (1,0) [0|1] "" NEO
SG_ BRAKE_ERROR_2 : 9|1@0+ (1,0) [0|1] "" NEO
SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 51|4@0+ (1,0) [0|3] "" NEO
BO_ 464 WHEEL_SPEEDS: 8 VSA
SG_ WHEEL_SPEED_FL : 7|15@0+ (0.002759506,0) [0|70] "m/s" NEO
SG_ WHEEL_SPEED_FR : 8|15@0+ (0.002759506,0) [0|70] "m/s" NEO
SG_ WHEEL_SPEED_RL : 25|15@0+ (0.002759506,0) [0|70] "m/s" NEO
SG_ WHEEL_SPEED_RR : 42|15@0+ (0.002759506,0) [0|70] "m/s" NEO
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" NEO
BO_ 476 XXX_5: 4 XXX
BO_ 490 VEHICLE_DYNAMICS: 8 VSA
SG_ LONG_ACCEL : 23|16@0- (0.0015384,0) [-20|20] "m/s2" NEO
BO_ 506 BRAKE_COMMAND: 8 ADAS
SG_ COMPUTER_BRAKE : 7|10@0+ (0.003906248,0) [0|1] "" EBCM
SG_ ZEROS_BOH : 13|5@0+ (1,0) [0|1] "" EBCM
SG_ COMPUTER_BRAKE_REQUEST : 8|1@0+ (1,0) [0|1] "" EBCM
SG_ CRUISE_BOH2 : 23|3@0+ (1,0) [0|1] "" EBCM
SG_ CRUISE_OVERRIDE : 20|1@0+ (1,0) [0|1] "" EBCM
SG_ CRUISE_BOH3 : 19|1@0+ (1,0) [0|1] "" EBCM
SG_ CRUISE_FAULT_CMD : 18|1@0+ (1,0) [0|1] "" EBCM
SG_ CRUISE_CANCEL_CMD : 17|1@0+ (1,0) [0|1] "" EBCM
SG_ COMPUTER_BRAKE_REQUEST_2 : 16|1@0+ (1,0) [0|1] "" EBCM
SG_ CRUISE_BOH4 : 31|8@0+ (1,0) [0|1] "" EBCM
SG_ BRAKE_LIGHTS : 39|1@0+ (1,0) [0|1] "" EBCM
SG_ CRUISE_BOH5 : 38|7@0+ (1,0) [0|1] "" EBCM
SG_ CHIME : 47|3@0+ (1,0) [0|7] "" EBCM
SG_ CRUISE_BOH6 : 44|1@0+ (1,0) [0|1] "" EBCM
SG_ FCW : 43|2@0+ (1,0) [0|3] "" EBCM
SG_ CRUISE_BOH7 : 41|10@0+ (1,0) [0|0] "" EBCM
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EBCM
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EBCM
BO_ 512 GAS_COMMAND: 3 NEO
SG_ GAS_COMMAND : 7|16@0+ (0.253984064,-83.3) [0|1] "" INTERCEPTOR
SG_ COUNTER : 21|2@0+ (1,0) [0|3] "" INTERCEPTOR
SG_ CHECKSUM : 19|4@0+ (1,0) [0|3] "" INTERCEPTOR
BO_ 513 GAS_SENSOR: 5 INTERCEPTOR
SG_ INTERCEPTOR_GAS : 7|16@0+ (0.253984064,-83.3) [0|1] "" NEO
SG_ INTERCEPTOR_GAS2 : 23|16@0+ (0.126992032,-83.3) [0|1] "" NEO
SG_ COUNTER : 37|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 35|4@0+ (1,0) [0|3] "" NEO
BO_ 542 XXX_6: 7 XXX
BO_ 545 XXX_7: 4 XXX
BO_ 597 ROUGH_WHEEL_SPEED: 8 VSA
SG_ WHEEL_SPEED_FL : 7|8@0+ (1,0) [0|255] "mph" NEO
SG_ WHEEL_SPEED_FR : 15|8@0+ (1,0) [0|255] "mph" NEO
SG_ WHEEL_SPEED_RL : 23|8@0+ (1,0) [0|255] "mph" NEO
SG_ WHEEL_SPEED_RR : 31|8@0+ (1,0) [0|255] "mph" NEO
SG_ SET_TO_X55 : 39|8@0+ (1,0) [0|255] "" NEO
SG_ SET_TO_X55 : 47|8@0+ (1,0) [0|255] "" NEO
BO_ 660 SCM_COMMANDS: 8 SCM
SG_ RIGHT_BLINKER : 6|1@0+ (1,0) [0|1] "" NEO
SG_ LEFT_BLINKER : 5|1@0+ (1,0) [0|1] "" NEO
SG_ WIPERS_SPEED : 4|2@0+ (1,0) [0|3] "" NEO
BO_ 773 SEATBELT_STATUS: 7 BDY
SG_ SEATBELT_DRIVER_LAMP : 7|1@0+ (1,0) [0|1] "" NEO
SG_ SEATBELT_DRIVER_LATCHED : 13|1@0+ (1,0) [0|1] "" NEO
SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 51|4@0+ (1,0) [0|3] "" NEO
BO_ 777 XXX_8: 8 XXX
BO_ 780 ACC_HUD: 8 ADAS
SG_ PCM_SPEED : 7|16@0+ (0.002763889,0) [0|100] "m/s" BDY
SG_ PCM_GAS : 23|7@0+ (1,0) [0|127] "" BDY
SG_ ZEROS_BOH : 16|1@0+ (1,0) [0|255] "" BDY
SG_ CRUISE_SPEED : 31|8@0+ (1,0) [0|255] "" BDY
SG_ DTC_MODE : 39|1@0+ (1,0) [0|1] "" BDY
SG_ BOH : 38|1@0+ (1,0) [0|1] "" BDY
SG_ ACC_PROBLEM : 37|1@0+ (1,0) [0|1] "" BDY
SG_ FCM_OFF : 36|1@0+ (1,0) [0|1] "" BDY
SG_ BOH_2 : 35|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_ SET_ME_X03 : 47|2@0+ (1,0) [0|3] "" BDY
SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" 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_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY
BO_ 800 XXX_9: 8 XXX
BO_ 804 CRUISE: 8 PCM
SG_ ENGINE_TEMPERATURE : 7|8@0+ (1,0) [0|255] "" NEO
SG_ BOH : 15|8@0+ (1,0) [0|255] "" NEO
SG_ TRIP_FUEL_CONSUMED : 23|16@0+ (1,0) [0|255] "" NEO
SG_ CRUISE_SPEED_PCM : 39|8@0+ (1,0) [0|255] "" NEO
SG_ BOH2 : 47|8@0- (1,0) [0|255] "" NEO
SG_ BOH3 : 55|8@0+ (1,0) [0|255] "" NEO
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" NEO
BO_ 808 XXX_10: 8 XXX
BO_ 819 XXX_11: 7 XXX
BO_ 821 XXX_12: 5 XXX
BO_ 829 LKAS_HUD_2: 5 ADAS
SG_ CAM_TEMP_HIGH : 7|1@0+ (1,0) [0|255] "" 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|3] "" BDY
BO_ 882 XXX_13: 2 XXX
BO_ 884 XXX_14: 7 XXX
BO_ 887 XXX_15: 8 XXX
BO_ 888 XXX_16: 8 XXX
BO_ 892 XXX_17: 8 XXX
BO_ 923 XXX_18: 2 XXX
BO_ 929 XXX_19: 4 XXX
BO_ 983 XXX_20: 8 XXX
BO_ 985 XXX_21: 3 XXX
BO_ 1024 XXX_22: 5 XXX
BO_ 1027 XXX_23: 5 XXX
BO_ 1029 DOORS_STATUS: 8 BDY
SG_ DOOR_OPEN_FL : 37|1@0+ (1,0) [0|1] "" NEO
SG_ DOOR_OPEN_FR : 38|1@0+ (1,0) [0|1] "" NEO
SG_ DOOR_OPEN_RL : 39|1@0+ (1,0) [0|1] "" NEO
SG_ DOOR_OPEN_RR : 40|1@0+ (1,0) [0|1] "" NEO
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" NEO
BO_ 1030 XXX_24: 5 VSA
BO_ 1034 XXX_25: 5 XXX
BO_ 1036 XXX_26: 8 XXX
BO_ 1039 XXX_27: 8 XXX
BO_ 1057 XXX_28: 5 EPS
BO_ 1064 XXX_29: 7 XXX
BO_ 1108 XXX_30: 8 XXX
BO_ 1365 XXX_31: 5 XXX
BO_ 1600 XXX_32: 5 XXX
BO_ 1601 XXX_33: 8 XXX
BO_TX_BU_ 228 : NEO,ADAS;
BO_TX_BU_ 506 : NEO,ADAS;
BO_TX_BU_ 780 : NEO,ADAS;
BO_TX_BU_ 829 : NEO,ADAS;
CM_ SG_ 419 GEAR "10 = reverse, 11 = transition";
CM_ SG_ 490 LONG_ACCEL "wheel speed derivative, noisy and zero snapping";
CM_ SG_ 780 CRUISE_SPEED "255 = no speed";
CM_ SG_ 804 CRUISE_SPEED_PCM "255 = no speed";
CM_ SG_ 829 BEEP "beeps are pleasant, chimes are for warnngs etc...";
VAL_ 399 STEER_STATUS 5 "fault" 4 "no_torque_alert_2" 2 "no_torque_alert_1" 0 "normal" ;
VAL_ 419 GEAR_SHIFTER 10 "S" 4 "D" 3 "N" 2 "R" 1 "P" ;
VAL_ 422 CRUISE_BUTTONS 7 "tbd" 6 "tbd" 5 "tbd" 4 "accel_res" 3 "decel_set" 2 "cancel" 1 "main" 0 "none" ;
VAL_ 422 LIGHTS_SETTING 3 "high_beam" 2 "low_beam" 1 "position" 0 "no_lights" ;
VAL_ 422 CRUISE_SETTING 3 "distance_adj" 2 "tbd" 1 "lkas_button" 0 "none" ;
VAL_ 506 CHIME 4 "double_chime" 3 "single_chime" 2 "continuous_chime" 1 "repeating_chime" 0 "no_chime" ;
VAL_ 506 FCW 3 "fcw" 2 "fcw" 1 "fcw" 0 "no_fcw" ;
VAL_ 780 HUD_LEAD 3 "no_car" 2 "solid_car" 1 "dashed_car" 0 "no_car" ;
VAL_ 829 BEEP 3 "single_beep" 2 "triple_beep" 1 "repeated_beep" 0 "no_beep" ;

View File

@@ -1,183 +0,0 @@
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_
BS_:
BU_: ADAS RADAR NEO XXX
BO_ 768 VEHICLE_STATE: 8 ADAS
SG_ SET_ME_XF9 : 7|8@0+ (1,0) [0|255] "" Vector__XXX
SG_ VEHICLE_SPEED : 15|8@0+ (1,0) [0|255] "kph" Vector__XXX
BO_ 769 VEHICLE_STATE2: 8 ADAS
SG_ SET_ME_0F18510 : 7|28@0+ (1,0) [0|268435455] "" Vector__XXX
SG_ SET_ME_25A0000 : 27|28@0+ (1,0) [0|268435455] "" Vector__XXX
BO_ 1024 XXX_100: 8 RADAR
BO_ 1040 XXX_101: 8 RADAR
BO_ 1041 XXX_102: 8 RADAR
BO_ 1042 XXX_103: 8 RADAR
BO_ 1043 XXX_104: 8 RADAR
BO_ 1044 XXX_105: 8 RADAR
BO_ 1045 XXX_106: 8 RADAR
BO_ 1046 XXX_107: 8 RADAR
BO_ 1047 XXX_108: 8 RADAR
BO_ 1056 XXX_109: 8 RADAR
BO_ 1057 XXX_110: 8 RADAR
BO_ 1058 XXX_111: 8 RADAR
BO_ 1059 XXX_112: 8 RADAR
BO_ 1060 XXX_113: 8 RADAR
BO_ 1072 TRACK_0: 8 RADAR
SG_ LONG_DIST : 7|12@0+ (0.0625,0) [0|255.5] "m" NEO
SG_ NEW_TRACK : 11|1@0+ (1,0) [0|1] "" NEO
SG_ LAT_DIST : 9|10@0- (0.0625,0) [0|63.5] "m" NEO
SG_ REL_SPEED : 31|12@0- (0.03125,0) [0|127.5] "m/s" NEO
BO_ 1073 TRACK_1: 8 RADAR
SG_ LONG_DIST : 7|12@0+ (0.0625,0) [0|255.5] "m" NEO
SG_ NEW_TRACK : 11|1@0+ (1,0) [0|1] "" NEO
SG_ LAT_DIST : 9|10@0- (0.0625,0) [0|63.5] "m" NEO
SG_ REL_SPEED : 31|12@0- (0.03125,0) [0|127.5] "m/s" NEO
BO_ 1074 TRACK_2: 8 RADAR
SG_ LONG_DIST : 7|12@0+ (0.0625,0) [0|255.5] "m" NEO
SG_ NEW_TRACK : 11|1@0+ (1,0) [0|1] "" NEO
SG_ LAT_DIST : 9|10@0- (0.0625,0) [0|63.5] "m" NEO
SG_ REL_SPEED : 31|12@0- (0.03125,0) [0|127.5] "m/s" NEO
BO_ 1075 TRACK_3: 8 RADAR
SG_ LONG_DIST : 7|12@0+ (0.0625,0) [0|255.5] "m" NEO
SG_ NEW_TRACK : 11|1@0+ (1,0) [0|1] "" NEO
SG_ LAT_DIST : 9|10@0- (0.0625,0) [0|63.5] "m" NEO
SG_ REL_SPEED : 31|12@0- (0.03125,0) [0|127.5] "m/s" NEO
BO_ 1076 TRACK_4: 8 RADAR
SG_ LONG_DIST : 7|12@0+ (0.0625,0) [0|255.5] "m" NEO
SG_ NEW_TRACK : 11|1@0+ (1,0) [0|1] "" NEO
SG_ LAT_DIST : 9|10@0- (0.0625,0) [0|63.5] "m" NEO
SG_ REL_SPEED : 31|12@0- (0.03125,0) [0|127.5] "m/s" NEO
BO_ 1077 TRACK_5: 8 RADAR
SG_ LONG_DIST : 7|12@0+ (0.0625,0) [0|255.5] "m" NEO
SG_ NEW_TRACK : 11|1@0+ (1,0) [0|1] "" NEO
SG_ LAT_DIST : 9|10@0- (0.0625,0) [0|63.5] "m" NEO
SG_ REL_SPEED : 31|12@0- (0.03125,0) [0|127.5] "m/s" NEO
BO_ 1078 TRACK_6: 8 RADAR
SG_ LONG_DIST : 7|12@0+ (0.0625,0) [0|255.5] "m" NEO
SG_ NEW_TRACK : 11|1@0+ (1,0) [0|1] "" NEO
SG_ LAT_DIST : 9|10@0- (0.0625,0) [0|63.5] "m" NEO
SG_ REL_SPEED : 31|12@0- (0.03125,0) [0|127.5] "m/s" NEO
BO_ 1079 TRACK_7: 8 RADAR
SG_ LONG_DIST : 7|12@0+ (0.0625,0) [0|255.5] "m" NEO
SG_ NEW_TRACK : 11|1@0+ (1,0) [0|1] "" NEO
SG_ LAT_DIST : 9|10@0- (0.0625,0) [0|63.5] "m" NEO
SG_ REL_SPEED : 31|12@0- (0.03125,0) [0|127.5] "m/s" NEO
BO_ 1080 TRACK_8: 8 RADAR
SG_ LONG_DIST : 7|12@0+ (0.0625,0) [0|255.5] "m" NEO
SG_ NEW_TRACK : 11|1@0+ (1,0) [0|1] "" NEO
SG_ LAT_DIST : 9|10@0- (0.0625,0) [0|63.5] "m" NEO
SG_ REL_SPEED : 31|12@0- (0.03125,0) [0|127.5] "m/s" NEO
BO_ 1081 TRACK_9: 8 RADAR
SG_ LONG_DIST : 7|12@0+ (0.0625,0) [0|255.5] "m" NEO
SG_ NEW_TRACK : 11|1@0+ (1,0) [0|1] "" NEO
SG_ LAT_DIST : 9|10@0- (0.0625,0) [0|63.5] "m" NEO
SG_ REL_SPEED : 31|12@0- (0.03125,0) [0|127.5] "m/s" NEO
BO_ 1088 TRACK_10: 8 RADAR
SG_ LONG_DIST : 7|12@0+ (0.0625,0) [0|255.5] "m" NEO
SG_ NEW_TRACK : 11|1@0+ (1,0) [0|1] "" NEO
SG_ LAT_DIST : 9|10@0- (0.0625,0) [0|63.5] "m" NEO
SG_ REL_SPEED : 31|12@0- (0.03125,0) [0|127.5] "m/s" NEO
BO_ 1089 TRACK_11: 8 RADAR
SG_ LONG_DIST : 7|12@0+ (0.0625,0) [0|255.5] "m" NEO
SG_ NEW_TRACK : 11|1@0+ (1,0) [0|1] "" NEO
SG_ LAT_DIST : 9|10@0- (0.0625,0) [0|63.5] "m" NEO
SG_ REL_SPEED : 31|12@0- (0.03125,0) [0|127.5] "m/s" NEO
BO_ 1090 TRACK_12: 8 RADAR
SG_ LONG_DIST : 7|12@0+ (0.0625,0) [0|255.5] "m" NEO
SG_ NEW_TRACK : 11|1@0+ (1,0) [0|1] "" NEO
SG_ LAT_DIST : 9|10@0- (0.0625,0) [0|63.5] "m" NEO
SG_ REL_SPEED : 31|12@0- (0.03125,0) [0|127.5] "m/s" NEO
BO_ 1091 TRACK_13: 8 RADAR
SG_ LONG_DIST : 7|12@0+ (0.0625,0) [0|255.5] "m" NEO
SG_ NEW_TRACK : 11|1@0+ (1,0) [0|1] "" NEO
SG_ LAT_DIST : 9|10@0- (0.0625,0) [0|63.5] "m" NEO
SG_ REL_SPEED : 31|12@0- (0.03125,0) [0|127.5] "m/s" NEO
BO_ 1092 TRACK_14: 8 RADAR
SG_ LONG_DIST : 7|12@0+ (0.0625,0) [0|255.5] "m" NEO
SG_ NEW_TRACK : 11|1@0+ (1,0) [0|1] "" NEO
SG_ LAT_DIST : 9|10@0- (0.0625,0) [0|63.5] "m" NEO
SG_ REL_SPEED : 31|12@0- (0.03125,0) [0|127.5] "m/s" NEO
BO_ 1093 TRACK_15: 8 RADAR
SG_ LONG_DIST : 7|12@0+ (0.0625,0) [0|255.5] "m" NEO
SG_ NEW_TRACK : 11|1@0+ (1,0) [0|1] "" NEO
SG_ LAT_DIST : 9|10@0- (0.0625,0) [0|63.5] "m" NEO
SG_ REL_SPEED : 31|12@0- (0.03125,0) [0|127.5] "m/s" NEO
BO_ 1279 XXX_114: 8 RADAR
BO_ 1280 XXX_115: 8 RADAR
BO_ 1296 XXX_116: 8 RADAR
BO_ 1297 XXX_117: 8 RADAR
BO_TX_BU_ 768 : NEO,ADAS;
BO_TX_BU_ 769 : NEO,ADAS;

View File

@@ -1,305 +0,0 @@
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_
BS_:
BU_: INTERCEPTOR EBCM NEO ADAS PCM EPS VSA SCM BDY XXX EPB
BO_ 57 XXX_1: 3 XXX
BO_ 342 STEERING_SENSORS: 6 EPS
SG_ STEER_ANGLE : 7|16@0- (-0.1,0) [-500|500] "deg" NEO
SG_ STEER_ANGLE_RATE : 23|16@0- (1,0) [-3000|3000] "deg/s" NEO
SG_ COUNTER : 45|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 43|4@0+ (1,0) [0|3] "" NEO
BO_ 344 POWERTRAIN_DATA: 8 PCM
SG_ XMISSION_SPEED : 7|16@0+ (0.002759506,0) [0|70] "m/s" NEO
SG_ ENGINE_RPM : 23|16@0+ (1,0) [0|15000] "rpm" NEO
SG_ XMISSION_SPEED2 : 39|16@0+ (0.002759506,0) [0|70] "m/s" NEO
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" NEO
BO_ 380 POWERTRAIN_DATA2: 8 PCM
SG_ PEDAL_GAS : 7|8@0+ (1,0) [0|255] "" NEO
SG_ ENGINE_RPM : 23|16@0+ (1,0) [0|15000] "rpm" NEO
SG_ GAS_PRESSED : 39|1@0+ (1,0) [0|1] "" NEO
SG_ ACC_STATUS : 38|1@0+ (1,0) [0|1] "rpm" NEO
SG_ BOH_17C : 37|5@0+ (1,0) [0|1] "rpm" NEO
SG_ BRAKE_LIGHTS_ON : 32|1@0+ (1,0) [0|1] "rpm" NEO
SG_ BOH2_17C : 47|10@0+ (1,0) [0|1] "rpm" NEO
SG_ BRAKE_PRESSED : 53|1@0+ (1,0) [0|1] "" NEO
SG_ BOH3_17C : 52|5@0+ (1,0) [0|1] "rpm" NEO
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" NEO
BO_ 401 GEARBOX: 8 PCM
SG_ GEAR_SHIFTER : 5|6@0+ (1,0) [0|63] "" NEO
SG_ GEAR : 35|4@0+ (1,0) [0|15] "" NEO
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" NEO
BO_ 420 VSA_STATUS: 8 VSA
SG_ USER_BRAKE : 7|16@0+ (0.015625,-1.609375) [0|1000] "" NEO
SG_ ESP_DISABLED : 28|1@0+ (1,0) [0|1] "" NEO
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" NEO
BO_ 422 SCM_BUTTONS: 8 SCM
SG_ CRUISE_BUTTONS : 7|3@0+ (1,0) [0|7] "" NEO
SG_ LIGHTS_SETTING : 1|2@0+ (1,0) [0|3] "" NEO
SG_ MAIN_ON : 47|1@0+ (1,0) [0|1] "" NEO
SG_ CRUISE_SETTING : 43|2@0+ (1,0) [0|3] "" NEO
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" NEO
BO_ 427 XXX_3: 3 VSA
BO_ 428 XXX_4: 8 XXX
BO_ 432 STANDSTILL: 7 VSA
SG_ WHEELS_MOVING : 12|1@0+ (1,0) [0|1] "" NEO
SG_ BRAKE_ERROR_1 : 11|1@0+ (1,0) [0|1] "" NEO
SG_ BRAKE_ERROR_2 : 9|1@0+ (1,0) [0|1] "" NEO
SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 51|4@0+ (1,0) [0|3] "" NEO
BO_ 450 XXX_5: 8 EPB
SG_ EPB_ACTIVE : 3|1@0+ (1,0) [0|1] "" NEO
SG_ EPB_STATE : 29|2@0+ (1,0) [0|3] "" NEO
BO_ 464 WHEEL_SPEEDS: 8 VSA
SG_ WHEEL_SPEED_FL : 7|15@0+ (0.002759506,0) [0|70] "m/s" NEO
SG_ WHEEL_SPEED_FR : 8|15@0+ (0.002759506,0) [0|70] "m/s" NEO
SG_ WHEEL_SPEED_RL : 25|15@0+ (0.002759506,0) [0|70] "m/s" NEO
SG_ WHEEL_SPEED_RR : 42|15@0+ (0.002759506,0) [0|70] "m/s" NEO
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" NEO
BO_ 470 XXX_6: 2 VSA
BO_ 476 XXX_7: 7 XXX
BO_ 487 XXX_8: 4 VSA
SG_ BRAKE_PRESSURE1 : 7|10@0+ (0.015625,-103) [0|1000] "" NEO
SG_ BRAKE_PRESSURE2 : 9|10@0+ (0.015625,-103) [0|1000] "" NEO
BO_ 490 VEHICLE_DYNAMICS: 8 VSA
SG_ LONG_ACCEL : 23|16@0- (0.0015384,0) [-20|20] "m/s2" NEO
BO_ 493 XXX_9: 5 VSA
BO_ 506 BRAKE_COMMAND: 8 ADAS
SG_ COMPUTER_BRAKE : 7|10@0+ (0.003906248,0) [0|1] "" EBCM
SG_ ZEROS_BOH : 13|5@0+ (1,0) [0|1] "" EBCM
SG_ COMPUTER_BRAKE_REQUEST : 8|1@0+ (1,0) [0|1] "" EBCM
SG_ CRUISE_BOH2 : 23|3@0+ (1,0) [0|1] "" EBCM
SG_ CRUISE_OVERRIDE : 20|1@0+ (1,0) [0|1] "" EBCM
SG_ CRUISE_BOH3 : 19|1@0+ (1,0) [0|1] "" EBCM
SG_ CRUISE_FAULT_CMD : 18|1@0+ (1,0) [0|1] "" EBCM
SG_ CRUISE_CANCEL_CMD : 17|1@0+ (1,0) [0|1] "" EBCM
SG_ COMPUTER_BRAKE_REQUEST_2 : 16|1@0+ (1,0) [0|1] "" EBCM
SG_ SET_ME_0X80 : 31|8@0+ (1,0) [0|1] "" EBCM
SG_ BRAKE_LIGHTS : 39|1@0+ (1,0) [0|1] "" EBCM
SG_ CRUISE_STATES : 38|7@0+ (1,0) [0|1] "" EBCM
SG_ CHIME : 47|3@0+ (1,0) [0|7] "" EBCM
SG_ ZEROS_BOH6 : 44|1@0+ (1,0) [0|1] "" EBCM
SG_ FCW : 43|1@0+ (1,0) [0|3] "" EBCM
SG_ ZEROS_BOH3 : 42|2@0+ (1,0) [0|0] "" EBCM
SG_ FCW2 : 40|1@0+ (1,0) [0|0] "" EBCM
SG_ ZEROS_BOH4 : 55|8@0+ (1,0) [0|0] "" EBCM
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EBCM
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EBCM
BO_ 512 GAS_COMMAND: 3 NEO
SG_ GAS_COMMAND : 7|16@0+ (0.253984064,-328) [0|1] "" INTERCEPTOR
SG_ COUNTER : 21|2@0+ (1,0) [0|3] "" INTERCEPTOR
SG_ CHECKSUM : 19|4@0+ (1,0) [0|3] "" INTERCEPTOR
BO_ 513 GAS_SENSOR: 5 INTERCEPTOR
SG_ INTERCEPTOR_GAS : 7|16@0+ (0.253984064,-328) [0|1] "" NEO
SG_ INTERCEPTOR_GAS2 : 23|16@0+ (0.126992032,-656) [0|1] "" NEO
SG_ COUNTER : 37|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 35|4@0+ (1,0) [0|3] "" NEO
BO_ 545 XXX_10: 6 XXX
BO_ 597 ROUGH_WHEEL_SPEED: 8 VSA
SG_ WHEEL_SPEED_FL : 7|8@0+ (1,0) [0|255] "mph" NEO
SG_ WHEEL_SPEED_FR : 15|8@0+ (1,0) [0|255] "mph" NEO
SG_ WHEEL_SPEED_RL : 23|8@0+ (1,0) [0|255] "mph" NEO
SG_ WHEEL_SPEED_RR : 31|8@0+ (1,0) [0|255] "mph" NEO
SG_ SET_TO_X55 : 39|8@0+ (1,0) [0|255] "" NEO
SG_ SET_TO_X55 : 47|8@0+ (1,0) [0|255] "" NEO
BO_ 660 SCM_COMMANDS: 8 SCM
SG_ RIGHT_BLINKER : 6|1@0+ (1,0) [0|1] "" NEO
SG_ LEFT_BLINKER : 5|1@0+ (1,0) [0|1] "" NEO
SG_ WIPERS_SPEED : 4|2@0+ (1,0) [0|3] "" NEO
BO_ 662 CRUISE_BUTTONS: 4 SCM
SG_ CRUISE_BUTTONS : 7|3@0+ (1,0) [0|7] "" NEO
SG_ CRUISE_SETTING : 3|2@0+ (1,0) [0|3] "" NEO
BO_ 773 SEATBELT_STATUS: 7 BDY
SG_ SEATBELT_DRIVER_LAMP : 7|1@0+ (1,0) [0|1] "" NEO
SG_ SEATBELT_DRIVER_LATCHED : 13|1@0+ (1,0) [0|1] "" NEO
SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 51|4@0+ (1,0) [0|3] "" NEO
BO_ 777 XXX_11: 8 XXX
BO_ 780 ACC_HUD: 8 ADAS
SG_ PCM_SPEED : 7|16@0+ (0.002763889,0) [0|100] "m/s" BDY
SG_ PCM_GAS : 23|7@0+ (1,0) [0|127] "" BDY
SG_ ZEROS_BOH : 16|1@0+ (1,0) [0|255] "" BDY
SG_ CRUISE_SPEED : 31|8@0+ (1,0) [0|255] "" BDY
SG_ DTC_MODE : 39|1@0+ (1,0) [0|1] "" BDY
SG_ BOH : 38|1@0+ (1,0) [0|1] "" BDY
SG_ ACC_PROBLEM : 37|1@0+ (1,0) [0|1] "" BDY
SG_ FCM_OFF : 36|1@0+ (1,0) [0|1] "" BDY
SG_ BOH_2 : 35|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_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY
SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" 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_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY
BO_ 795 XXX_12: 8 XXX
BO_ 800 XXX_13: 8 XXX
BO_ 804 CRUISE: 8 PCM
SG_ ENGINE_TEMPERATURE : 7|8@0+ (1,0) [0|255] "" NEO
SG_ BOH : 15|8@0+ (1,0) [0|255] "" NEO
SG_ TRIP_FUEL_CONSUMED : 23|16@0+ (1,0) [0|255] "" NEO
SG_ CRUISE_SPEED_PCM : 39|8@0+ (1,0) [0|255] "" NEO
SG_ BOH2 : 47|8@0- (1,0) [0|255] "" NEO
SG_ BOH3 : 55|8@0+ (1,0) [0|255] "" NEO
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" NEO
BO_ 808 XXX_14: 8 XXX
BO_ 829 LKAS_HUD_2: 5 ADAS
SG_ CAM_TEMP_HIGH : 7|1@0+ (1,0) [0|255] "" 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|3] "" BDY
BO_ 862 XXX_15: 8 ADAS
SG_ UI_ALERTS : 7|56@0+ (1,0) [0|127] "" BDY
BO_ 884 XXX_16: 8 XXX
BO_ 891 XXX_17: 8 XXX
BO_ 892 XXX_18: 8 XXX
BO_ 927 XXX_19: 8 ADAS
SG_ ZEROS_BOH : 7|17@0+ (1,0) [0|127] "" BDY
SG_ APPLY_BRAKES_FOR_CANC : 23|1@0+ (1,0) [0|15] "" BDY
SG_ ZEROS_BOH2 : 22|1@0+ (1,0) [0|1] "" BDY
SG_ RESUME_INSTRUCTION : 21|1@0+ (1,0) [0|15] "" BDY
SG_ ACC_ALERTS : 20|5@0+ (1,0) [0|15] "" BDY
SG_ ZEROS_BOH2 : 31|8@0+ (1,0) [0|127] "" BDY
SG_ LEAD_SPEED : 39|9@0+ (1,0) [0|127] "" BDY
SG_ LEAD_STATE : 46|3@0+ (1,0) [0|127] "" BDY
SG_ LEAD_DISTANCE : 43|5@0+ (1,0) [0|31] "" BDY
SG_ ZEROS_BOH3 : 54|7@0+ (1,0) [0|127] "" BDY
BO_ 929 XXX_20: 8 XXX
BO_ 985 XXX_21: 3 XXX
BO_ 1024 XXX_22: 5 XXX
BO_ 1027 XXX_23: 5 XXX
BO_ 1029 DOORS_STATUS: 8 BDY
SG_ DOOR_OPEN_FL : 37|1@0+ (1,0) [0|1] "" NEO
SG_ DOOR_OPEN_FR : 38|1@0+ (1,0) [0|1] "" NEO
SG_ DOOR_OPEN_RL : 39|1@0+ (1,0) [0|1] "" NEO
SG_ DOOR_OPEN_RR : 40|1@0+ (1,0) [0|1] "" NEO
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" NEO
BO_ 1036 XXX_24: 8 XXX
BO_ 1039 XXX_25: 8 XXX
BO_ 1108 XXX_26: 8 XXX
BO_ 1302 XXX_27: 8 XXX
BO_ 1322 XXX_28: 5 XXX
BO_ 1361 XXX_29: 5 XXX
BO_ 1365 XXX_30: 5 XXX
BO_ 1424 XXX_31: 5 XXX
BO_ 1600 XXX_32: 5 XXX
BO_ 1601 XXX_33: 8 XXX
BO_ 1633 XXX_34: 8 XXX
BO_TX_BU_ 228 : NEO,ADAS;
BO_TX_BU_ 506 : NEO,ADAS;
BO_TX_BU_ 780 : NEO,ADAS;
BO_TX_BU_ 829 : NEO,ADAS;
BO_TX_BU_ 862 : NEO,ADAS;
BO_TX_BU_ 927 : NEO,ADAS;

View File

@@ -1,343 +0,0 @@
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_
BS_:
BU_: INTERCEPTOR EBCM NEO ADAS PCM EPS VSA SCM BDY XXX EPB
BO_ 57 XXX_1: 3 XXX
BO_ 148 XXX_2: 8 XXX
SG_ LAT_ACCEL : 7|10@0+ (0.02,-512) [-20|20] "m/s2" NEO
SG_ LONG_ACCEL : 24|9@0- (-0.02,0) [-20|20] "m/s2" NEO
BO_ 228 STEERING_CONTROL: 5 ADAS
SG_ STEER_TORQUE : 7|16@0- (1,0) [-3840|3840] "" EPS
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_ CHECKSUM : 39|4@0+ (1,0) [0|15] "" EPS
SG_ COUNTER : 33|2@0+ (1,0) [0|3] "" EPS
BO_ 304 GAS_PEDAL2: 8 PCM
SG_ ENGINE_TORQUE_ESTIMATE : 7|16@0- (1,0) [-1000|1000] "Nm" NEO
SG_ ENGINE_TORQUE_REQUEST : 23|16@0- (1,0) [-1000|1000] "Nm" NEO
SG_ CAR_GAS : 39|8@0+ (1,0) [0|255] "" NEO
BO_ 330 STEERING_SENSORS: 8 EPS
SG_ STEER_ANGLE : 7|16@0- (-0.1,0) [-500|500] "deg" NEO
SG_ STEER_ANGLE_RATE : 23|16@0- (-1,0) [-3000|3000] "deg/s" NEO
SG_ STEER_ANGLE_OFFSET : 39|8@0- (-0.1,0) [-128|127] "deg" NEO
SG_ STEER_WHEEL_ANGLE : 47|16@0- (-0.1,0) [-500|500] "deg" NEO
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" NEO
BO_ 344 POWERTRAIN_DATA: 8 PCM
SG_ XMISSION_SPEED : 7|16@0+ (0.002759506,0) [0|70] "m/s" NEO
SG_ ENGINE_RPM : 23|16@0+ (1,0) [0|15000] "rpm" NEO
SG_ XMISSION_SPEED2 : 39|16@0+ (0.002759506,0) [0|70] "m/s" NEO
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" NEO
BO_ 380 POWERTRAIN_DATA2: 8 PCM
SG_ PEDAL_GAS : 7|8@0+ (1,0) [0|255] "" NEO
SG_ ENGINE_RPM : 23|16@0+ (1,0) [0|15000] "rpm" NEO
SG_ GAS_PRESSED : 39|1@0+ (1,0) [0|1] "" NEO
SG_ ACC_STATUS : 38|1@0+ (1,0) [0|1] "rpm" NEO
SG_ BOH_17C : 37|5@0+ (1,0) [0|1] "rpm" NEO
SG_ BRAKE_LIGHTS_ON : 32|1@0+ (1,0) [0|1] "rpm" NEO
SG_ BOH2_17C : 47|10@0+ (1,0) [0|1] "rpm" NEO
SG_ BRAKE_PRESSED : 53|1@0+ (1,0) [0|1] "" NEO
SG_ BOH3_17C : 52|5@0+ (1,0) [0|1] "rpm" NEO
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" NEO
BO_ 399 STEER_STATUS: 7 EPS
SG_ STEER_TORQUE_SENSOR : 7|16@0- (1,0) [-31000|31000] "tbd" NEO
SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" NEO
SG_ STEER_STATUS : 39|4@0+ (1,0) [0|15] "" NEO
SG_ STEER_CONTROL_ACTIVE : 35|1@0+ (1,0) [0|1] "" NEO
SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 51|4@0+ (1,0) [0|3] "" NEO
BO_ 401 GEARBOX: 8 PCM
SG_ GEAR_SHIFTER : 5|6@0+ (1,0) [0|63] "" NEO
SG_ GEAR : 35|4@0+ (1,0) [0|15] "" NEO
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" NEO
BO_ 420 VSA_STATUS: 8 VSA
SG_ USER_BRAKE : 7|16@0+ (0.015625,-1.609375) [0|1000] "" NEO
SG_ ESP_DISABLED : 28|1@0+ (1,0) [0|1] "" NEO
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" NEO
BO_ 427 XXX_3: 3 VSA
BO_ 428 XXX_4: 8 XXX
BO_ 432 STANDSTILL: 7 VSA
SG_ WHEELS_MOVING : 12|1@0+ (1,0) [0|1] "" NEO
SG_ BRAKE_ERROR_1 : 11|1@0+ (1,0) [0|1] "" NEO
SG_ BRAKE_ERROR_2 : 9|1@0+ (1,0) [0|1] "" NEO
SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 51|4@0+ (1,0) [0|3] "" NEO
BO_ 450 XXX_5: 8 EPB
SG_ EPB_ACTIVE : 3|1@0+ (1,0) [0|1] "" NEO
SG_ EPB_STATE : 29|2@0+ (1,0) [0|3] "" NEO
BO_ 464 WHEEL_SPEEDS: 8 VSA
SG_ WHEEL_SPEED_FL : 7|15@0+ (0.002759506,0) [0|70] "m/s" NEO
SG_ WHEEL_SPEED_FR : 8|15@0+ (0.002759506,0) [0|70] "m/s" NEO
SG_ WHEEL_SPEED_RL : 25|15@0+ (0.002759506,0) [0|70] "m/s" NEO
SG_ WHEEL_SPEED_RR : 42|15@0+ (0.002759506,0) [0|70] "m/s" NEO
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" NEO
BO_ 470 XXX_6: 2 VSA
BO_ 476 XXX_7: 7 XXX
BO_ 487 XXX_8: 4 VSA
SG_ BRAKE_PRESSURE1 : 7|10@0+ (0.015625,-103) [0|1000] "" NEO
SG_ BRAKE_PRESSURE2 : 9|10@0+ (0.015625,-103) [0|1000] "" NEO
BO_ 490 VEHICLE_DYNAMICS: 8 VSA
SG_ LONG_ACCEL : 23|16@0- (0.0015384,0) [-20|20] "m/s2" NEO
BO_ 493 XXX_9: 5 VSA
BO_ 506 BRAKE_COMMAND: 8 ADAS
SG_ COMPUTER_BRAKE : 7|10@0+ (0.003906248,0) [0|1] "" EBCM
SG_ ZEROS_BOH : 13|5@0+ (1,0) [0|1] "" EBCM
SG_ COMPUTER_BRAKE_REQUEST : 8|1@0+ (1,0) [0|1] "" EBCM
SG_ CRUISE_BOH2 : 23|3@0+ (1,0) [0|1] "" EBCM
SG_ CRUISE_OVERRIDE : 20|1@0+ (1,0) [0|1] "" EBCM
SG_ CRUISE_BOH3 : 19|1@0+ (1,0) [0|1] "" EBCM
SG_ CRUISE_FAULT_CMD : 18|1@0+ (1,0) [0|1] "" EBCM
SG_ CRUISE_CANCEL_CMD : 17|1@0+ (1,0) [0|1] "" EBCM
SG_ COMPUTER_BRAKE_REQUEST_2 : 16|1@0+ (1,0) [0|1] "" EBCM
SG_ SET_ME_0X80 : 31|8@0+ (1,0) [0|1] "" EBCM
SG_ BRAKE_LIGHTS : 39|1@0+ (1,0) [0|1] "" EBCM
SG_ CRUISE_STATES : 38|7@0+ (1,0) [0|1] "" EBCM
SG_ CHIME : 47|3@0+ (1,0) [0|7] "" EBCM
SG_ ZEROS_BOH6 : 44|1@0+ (1,0) [0|1] "" EBCM
SG_ FCW : 43|1@0+ (1,0) [0|3] "" EBCM
SG_ ZEROS_BOH3 : 42|2@0+ (1,0) [0|0] "" EBCM
SG_ FCW2 : 40|1@0+ (1,0) [0|0] "" EBCM
SG_ ZEROS_BOH4 : 55|8@0+ (1,0) [0|0] "" EBCM
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EBCM
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EBCM
BO_ 512 GAS_COMMAND: 3 NEO
SG_ GAS_COMMAND : 7|16@0+ (0.253984064,-328) [0|1] "" INTERCEPTOR
SG_ COUNTER : 21|2@0+ (1,0) [0|3] "" INTERCEPTOR
SG_ CHECKSUM : 19|4@0+ (1,0) [0|3] "" INTERCEPTOR
BO_ 513 GAS_SENSOR: 5 INTERCEPTOR
SG_ INTERCEPTOR_GAS : 7|16@0+ (0.253984064,-328) [0|1] "" NEO
SG_ INTERCEPTOR_GAS2 : 23|16@0+ (0.126992032,-656) [0|1] "" NEO
SG_ COUNTER : 37|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 35|4@0+ (1,0) [0|3] "" NEO
BO_ 545 XXX_10: 6 XXX
BO_ 597 ROUGH_WHEEL_SPEED: 8 VSA
SG_ WHEEL_SPEED_FL : 7|8@0+ (1,0) [0|255] "mph" NEO
SG_ WHEEL_SPEED_FR : 15|8@0+ (1,0) [0|255] "mph" NEO
SG_ WHEEL_SPEED_RL : 23|8@0+ (1,0) [0|255] "mph" NEO
SG_ WHEEL_SPEED_RR : 31|8@0+ (1,0) [0|255] "mph" NEO
SG_ SET_TO_X55 : 39|8@0+ (1,0) [0|255] "" NEO
SG_ SET_TO_X55 : 47|8@0+ (1,0) [0|255] "" NEO
BO_ 662 CRUISE_BUTTONS: 4 SCM
SG_ CRUISE_BUTTONS : 7|3@0+ (1,0) [0|7] "" NEO
SG_ CRUISE_SETTING : 3|2@0+ (1,0) [0|3] "" NEO
BO_ 773 SEATBELT_STATUS: 7 BDY
SG_ SEATBELT_DRIVER_LAMP : 7|1@0+ (1,0) [0|1] "" NEO
SG_ SEATBELT_DRIVER_LATCHED : 13|1@0+ (1,0) [0|1] "" NEO
SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 51|4@0+ (1,0) [0|3] "" NEO
BO_ 777 XXX_11: 8 XXX
BO_ 780 ACC_HUD: 8 ADAS
SG_ PCM_SPEED : 7|16@0+ (0.002759506,0) [0|100] "m/s" BDY
SG_ PCM_GAS : 23|7@0+ (1,0) [0|127] "" BDY
SG_ ZEROS_BOH : 16|1@0+ (1,0) [0|255] "" BDY
SG_ CRUISE_SPEED : 31|8@0+ (1,0) [0|255] "" BDY
SG_ DTC_MODE : 39|1@0+ (1,0) [0|1] "" BDY
SG_ BOH : 38|1@0+ (1,0) [0|1] "" BDY
SG_ ACC_PROBLEM : 37|1@0+ (1,0) [0|1] "" BDY
SG_ FCM_OFF : 36|1@0+ (1,0) [0|1] "" BDY
SG_ BOH_2 : 35|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_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY
SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" 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_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY
BO_ 795 XXX_12: 8 XXX
BO_ 800 XXX_13: 8 XXX
BO_ 804 CRUISE: 8 PCM
SG_ ENGINE_TEMPERATURE : 7|8@0+ (1,0) [0|255] "" NEO
SG_ BOH : 15|8@0+ (1,0) [0|255] "" NEO
SG_ TRIP_FUEL_CONSUMED : 23|16@0+ (1,0) [0|255] "" NEO
SG_ CRUISE_SPEED_PCM : 39|8@0+ (1,0) [0|255] "" NEO
SG_ BOH2 : 47|8@0- (1,0) [0|255] "" NEO
SG_ BOH3 : 55|8@0+ (1,0) [0|255] "" NEO
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" NEO
BO_ 806 SCM_FEEDBACK: 8 SCM
SG_ CMBS_BUTTON : 22|2@0+ (1,0) [0|3] "" NEO
SG_ MAIN_ON : 28|1@0+ (1,0) [0|1] "" NEO
SG_ RIGHT_BLINKER : 27|1@0+ (1,0) [0|1] "" NEO
SG_ LEFT_BLINKER : 26|1@0+ (1,0) [0|1] "" NEO
BO_ 808 XXX_14: 8 XXX
BO_ 829 LKAS_HUD_2: 5 ADAS
SG_ CAM_TEMP_HIGH : 7|1@0+ (1,0) [0|255] "" 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|3] "" BDY
BO_ 862 XXX_15: 8 ADAS
SG_ UI_ALERTS : 7|56@0+ (1,0) [0|127] "" BDY
BO_ 884 XXX_16: 8 XXX
BO_ 891 XXX_17: 8 XXX
BO_ 892 XXX_18: 8 XXX
BO_ 927 XXX_19: 8 ADAS
SG_ ZEROS_BOH : 7|17@0+ (1,0) [0|127] "" BDY
SG_ APPLY_BRAKES_FOR_CANC : 23|1@0+ (1,0) [0|15] "" BDY
SG_ ZEROS_BOH2 : 22|1@0+ (1,0) [0|1] "" BDY
SG_ RESUME_INSTRUCTION : 21|1@0+ (1,0) [0|15] "" BDY
SG_ ACC_ALERTS : 20|5@0+ (1,0) [0|15] "" BDY
SG_ ZEROS_BOH2 : 31|8@0+ (1,0) [0|127] "" BDY
SG_ LEAD_SPEED : 39|9@0+ (1,0) [0|127] "" BDY
SG_ LEAD_STATE : 46|3@0+ (1,0) [0|127] "" BDY
SG_ LEAD_DISTANCE : 43|5@0+ (1,0) [0|31] "" BDY
SG_ ZEROS_BOH3 : 54|7@0+ (1,0) [0|127] "" BDY
BO_ 929 XXX_20: 8 XXX
BO_ 985 XXX_21: 3 XXX
BO_ 1024 XXX_22: 5 XXX
BO_ 1027 XXX_23: 5 XXX
BO_ 1029 DOORS_STATUS: 8 BDY
SG_ DOOR_OPEN_FL : 37|1@0+ (1,0) [0|1] "" NEO
SG_ DOOR_OPEN_FR : 38|1@0+ (1,0) [0|1] "" NEO
SG_ DOOR_OPEN_RL : 39|1@0+ (1,0) [0|1] "" NEO
SG_ DOOR_OPEN_RR : 40|1@0+ (1,0) [0|1] "" NEO
SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" NEO
SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" NEO
BO_ 1036 XXX_24: 8 XXX
BO_ 1039 XXX_25: 8 XXX
BO_ 1108 XXX_26: 8 XXX
BO_ 1302 XXX_27: 8 XXX
BO_ 1322 XXX_28: 5 XXX
BO_ 1361 XXX_29: 5 XXX
BO_ 1365 XXX_30: 5 XXX
BO_ 1424 XXX_31: 5 XXX
BO_ 1600 XXX_32: 5 XXX
BO_ 1601 XXX_33: 8 XXX
BO_ 1633 XXX_34: 8 XXX
BO_TX_BU_ 228 : NEO,ADAS;
BO_TX_BU_ 506 : NEO,ADAS;
BO_TX_BU_ 780 : NEO,ADAS;
BO_TX_BU_ 829 : NEO,ADAS;
BO_TX_BU_ 862 : NEO,ADAS;
BO_TX_BU_ 927 : NEO,ADAS;
CM_ SG_ 401 GEAR "10 = reverse, 11 = transition";
CM_ SG_ 490 LONG_ACCEL "wheel speed derivative, noisy and zero snapping";
CM_ SG_ 780 CRUISE_SPEED "255 = no speed";
CM_ SG_ 804 CRUISE_SPEED_PCM "255 = no speed";
CM_ SG_ 829 BEEP "beeps are pleasant, chimes are for warnngs etc...";
VAL_ 399 STEER_STATUS 5 "fault" 4 "no_torque_alert_2" 2 "no_torque_alert_1" 0 "normal" ;
VAL_ 401 GEAR_SHIFTER 32 "L" 16 "S" 8 "D" 4 "N" 2 "R" 1 "P" ;
VAL_ 450 EPB_STATE 3 "engaged" 2 "disengaging" 1 "engaging" 0 "disengaged" ;
VAL_ 506 CHIME 4 "double_chime" 3 "single_chime" 2 "continuous_chime" 1 "repeating_chime" 0 "no_chime" ;
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_ 780 CRUISE_SPEED 255 "no_speed" 252 "stopped" ;
VAL_ 780 HUD_LEAD 3 "acc_off" 2 "solid_car" 1 "dashed_car" 0 "no_car" ;
VAL_ 806 CMBS_BUTTON 3 "pressed" 0 "released" ;
VAL_ 829 BEEP 3 "single_beep" 2 "triple_beep" 1 "repeated_beep" 0 "no_beep" ;
VAL_ 927 ACC_ALERTS 29 "esp_active_acc_canceled" 10 "b_pedal_applied" 9 "speed_too_low" 8 "speed_too_high" 7 "p_brake_applied" 6 "gear_no_d" 5 "seatbelt" 4 "too_steep_downhill" 3 "too_steep_uphill" 2 "too_close" 1 "no_vehicle_ahead" ;

View File

@@ -1,405 +0,0 @@
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_
BS_:
BU_:
NEO
MCU
GTW
EPAS
DI
ESP
SBW
STW
VAL_TABLE_ StW_AnglHP_Spd 16383 "SNA" ;
VAL_TABLE_ DI_aebFaultReason 15 "DI_AEB_FAULT_DAS_REQ_DI_UNAVAIL" 14 "DI_AEB_FAULT_ACCEL_REQ_INVALID" 13 "DI_AEB_FAULT_MIN_TIME_BTWN_EVENTS" 12 "DI_AEB_FAULT_ESP_MIA" 11 "DI_AEB_FAULT_ESP_FAULT" 10 "DI_AEB_FAULT_EPB_NOT_PARKED" 9 "DI_AEB_FAULT_ACCEL_OUT_OF_BOUNDS" 8 "DI_AEB_FAULT_PM_REQUEST" 7 "DI_AEB_FAULT_VEL_EST_ABNORMAL" 6 "DI_AEB_FAULT_DAS_SNA" 5 "DI_AEB_FAULT_DAS_CONTROL_MIA" 4 "DI_AEB_FAULT_SPEED_DELTA" 3 "DI_AEB_FAULT_EBR_FAULT" 2 "DI_AEB_FAULT_PM_MIA" 1 "DI_AEB_FAULT_EPB_MIA" 0 "DI_AEB_FAULT_NONE" ;
VAL_TABLE_ DI_aebLockState 3 "AEB_LOCK_STATE_SNA" 2 "AEB_LOCK_STATE_UNUSED" 1 "AEB_LOCK_STATE_UNLOCKED" 0 "AEB_LOCK_STATE_LOCKED" ;
VAL_TABLE_ DI_aebSmState 7 "DI_AEB_STATE_FAULT" 6 "DI_AEB_STATE_EXIT" 5 "DI_AEB_STATE_STANDSTILL" 4 "DI_AEB_STATE_STOPPING" 3 "DI_AEB_STATE_ENABLE" 2 "DI_AEB_STATE_ENABLE_INIT" 1 "DI_AEB_STATE_STANDBY" 0 "DI_AEB_STATE_UNAVAILABLE" ;
VAL_TABLE_ DI_aebState 7 "AEB_CAN_STATE_SNA" 4 "AEB_CAN_STATE_FAULT" 3 "AEB_CAN_STATE_STANDSTILL" 2 "AEB_CAN_STATE_ENABLED" 1 "AEB_CAN_STATE_STANDBY" 0 "AEB_CAN_STATE_UNAVAILABLE" ;
VAL_TABLE_ DI_epbInterfaceReady 1 "EPB_INTERFACE_READY" 0 "EPB_INTERFACE_NOT_READY" ;
VAL_TABLE_ DI_gear 7 "DI_GEAR_SNA" 4 "DI_GEAR_D" 3 "DI_GEAR_N" 2 "DI_GEAR_R" 1 "DI_GEAR_P" 0 "DI_GEAR_INVALID" ;
VAL_TABLE_ DI_gpoReason 8 "DI_GPO_NUMREASONS" 7 "DI_GPO_CAPACITOR_OVERTEMP" 6 "DI_GPO_NOT_ENOUGH_12V" 5 "DI_GPO_NO_BATTERY_POWER" 4 "DI_GPO_AMBIENT_OVERTEMP" 3 "DI_GPO_FLUID_DELTAT" 2 "DI_GPO_STATOR_OVERTEMP" 1 "DI_GPO_HEATSINK_OVERTEMP" 0 "DI_GPO_OUTLET_OVERTEMP" ;
VAL_TABLE_ DI_immobilizerCondition 1 "DI_IMM_CONDITION_LEARNED" 0 "DI_IMM_CONDITION_VIRGIN_SNA" ;
VAL_TABLE_ DI_immobilizerState 7 "DI_IMM_STATE_FAULT" 6 "DI_IMM_STATE_FAULTRETRY" 5 "DI_IMM_STATE_RESET" 4 "DI_IMM_STATE_LEARN" 3 "DI_IMM_STATE_DISARMED" 2 "DI_IMM_STATE_AUTHENTICATING" 1 "DI_IMM_STATE_REQUEST" 0 "DI_IMM_STATE_INIT_SNA" ;
VAL_TABLE_ DI_limpReason 24 "DI_LIMP_NUMREASONS" 23 "DI_LIMP_CAPACITOR_OVERTEMP" 22 "DI_LIMP_GTW_MIA" 21 "DI_LIMP_TRQCMD_VALIDITY_UNKNOWN" 20 "DI_LIMP_DI_MIA" 19 "DI_LIMP_CONFIG_MISMATCH" 18 "DI_LIMP_HEATSINK_TEMP" 17 "DI_LIMP_PMREQUEST" 16 "DI_LIMP_PMHEARTBEAT" 15 "DI_LIMP_TRQ_CROSS_CHECK" 14 "DI_LIMP_EXTERNAL_COMMAND" 13 "DI_LIMP_WRONG_CS_CALIBRATION" 12 "DI_LIMP_STATOR_TEMP" 11 "DI_LIMP_DELTAT_TOO_NEGATIVE" 10 "DI_LIMP_DELTAT_TOO_POSITIVE" 9 "DI_LIMP_AMBIENT_TEMP" 8 "DI_LIMP_OUTLET_TEMP" 7 "DI_LIMP_LOW_FLOW" 6 "DI_LIMP_BMS_MIA" 5 "DI_LIMP_12V_SUPPLY_UNDERVOLTAGE" 4 "DI_LIMP_NO_FLUID" 3 "DI_LIMP_NO_FUNC_HEATSINK_SENSOR" 2 "DI_LIMP_NO_FUNC_STATORT_SENSOR" 1 "DI_LIMP_BUSV_SENSOR_IRRATIONAL" 0 "DI_LIMP_PHASE_IMBALANCE" ;
VAL_TABLE_ DI_mode 2 "DI_MODE_DYNO" 1 "DI_MODE_DRIVE" 0 "DI_MODE_UNDEF" ;
VAL_TABLE_ DI_motorType 14 "DI_MOTOR_F2AE" 13 "DI_MOTOR_F2AD" 12 "DI_MOTOR_F2AC" 11 "DI_MOTOR_F2AB" 10 "DI_MOTOR_F1AC" 9 "DI_MOTOR_SSR1A" 8 "DI_MOTOR_F1A" 7 "DI_MOTOR_M7M6" 6 "DI_MOTOR_M8A" 5 "DI_MOTOR_M7M5" 4 "DI_MOTOR_M7M4" 3 "DI_MOTOR_M7M3" 2 "DI_MOTOR_ROADSTER_SPORT" 1 "DI_MOTOR_ROADSTER_BASE" 0 "DI_MOTOR_SNA" ;
VAL_TABLE_ DI_speedUnits 1 "DI_SPEED_KPH" 0 "DI_SPEED_MPH" ;
VAL_TABLE_ DI_state 4 "DI_STATE_ENABLE" 3 "DI_STATE_FAULT" 2 "DI_STATE_CLEAR_FAULT" 1 "DI_STATE_STANDBY" 0 "DI_STATE_PREAUTH" ;
VAL_TABLE_ DI_velocityEstimatorState 4 "VE_STATE_BACKUP_MOTOR" 3 "VE_STATE_BACKUP_WHEELS_B" 2 "VE_STATE_BACKUP_WHEELS_A" 1 "VE_STATE_WHEELS_NORMAL" 0 "VE_STATE_NOT_INITIALIZED" ;
BO_ 1160 DAS_steeringControl: 4 NEO
SG_ DAS_steeringControlType : 23|2@0+ (1,0) [0|0] "" EPAS
SG_ DAS_steeringControlChecksum : 31|8@0+ (1,0) [0|0] "" EPAS
SG_ DAS_steeringControlCounter : 19|4@0+ (1,0) [0|0] "" EPAS
SG_ DAS_steeringAngleRequest : 6|15@0+ (0.1,-1638.35) [-1638.35|1638.35] "deg" EPAS
SG_ DAS_steeringHapticRequest : 7|1@0+ (1,0) [0|0] "" EPAS
BO_ 257 GTW_epasControl: 3 NEO
SG_ GTW_epasControlChecksum : 16|8@1+ (1,0) [0|255] "" NEO
SG_ GTW_epasControlCounter : 12|4@1+ (1,0) [0|15] "" NEO
SG_ GTW_epasControlType : 8|2@1+ (1,0) [4|-1] "" NEO
SG_ GTW_epasEmergencyOn : 0|1@1+ (1,0) [2|-1] "" NEO
SG_ GTW_epasLDWEnabled : 11|1@1+ (1,0) [2|-1] "" NEO
SG_ GTW_epasPowerMode : 1|4@1+ (1,0) [4|14] "" NEO
SG_ GTW_epasTuneRequest : 5|3@1+ (1,0) [8|-1] "" NEO
BO_ 880 EPAS_sysStatus: 8 EPAS
SG_ EPAS_currentTuneMode : 0|4@1+ (1,0) [8|15] "" NEO
SG_ EPAS_eacErrorCode : 16|4@1+ (1,0) [16|-1] "" NEO
SG_ EPAS_eacStatus : 48|3@1+ (1,0) [5|7] "" NEO
SG_ EPAS_handsOnLevel : 32|2@1+ (1,0) [4|-1] "" NEO
SG_ EPAS_internalSAS : 37|14@0+ (0.10,-819.200010) [0|0] "deg" NEO
SG_ EPAS_steeringFault : 5|1@1+ (1,0) [2|-1] "" NEO
SG_ EPAS_steeringRackForce : 1|10@0+ (50,-25575) [0|0] "N" NEO
SG_ EPAS_steeringReduced : 4|1@1+ (1,0) [2|-1] "" NEO
SG_ EPAS_sysStatusChecksum : 56|8@1+ (1,0) [0|255] "" NEO
SG_ EPAS_sysStatusCounter : 52|4@1+ (1,0) [0|15] "" NEO
SG_ EPAS_torsionBarTorque : 19|12@0+ (0.010,-20.50) [0|0] "Nm" NEO
BO_ 3 STW_ANGL_STAT: 8 STW
SG_ CRC_STW_ANGL_STAT : 56|8@1+ (1,0) [0|255] "" NEO
SG_ MC_STW_ANGL_STAT : 52|4@1+ (1,0) [0|15] "" NEO
SG_ StW_Angl : 5|14@0+ (0.50,-2048) [0|0] "deg" NEO
SG_ StW_AnglSens_Id : 36|2@1+ (1,0) [3|3] "" NEO
SG_ StW_AnglSens_Stat : 38|2@1+ (1,0) [4|-1] "" NEO
SG_ StW_AnglSpd : 21|14@0+ (0.50,-2048) [0|0] "/s" NEO
BO_ 14 STW_ANGLHP_STAT: 8 GTW
SG_ StW_AnglHP : 5|14@0+ (0.1,-819.2) [-819.2|819] "deg" NEO
SG_ StW_AnglHP_Spd : 21|14@0+ (0.5,-4096) [-4096|4095.5] "deg/s" NEO
SG_ StW_AnglHP_Sens_Stat : 33|2@0+ (1,0) [0|0] "" NEO
SG_ StW_AnglHP_Sens_Id : 35|2@0+ (1,0) [0|0] "" NEO
SG_ MC_STW_ANGLHP_STAT : 55|4@0+ (1,0) [0|15] "" NEO
SG_ CRC_STW_ANGLHP_STAT : 63|8@0+ (1,0) [0|0] "" NEO
BO_ 264 DI_torque1: 8 DI
SG_ DI_torqueDriver : 0|13@1- (0.25,0) [-750|750] "Nm" NEO
SG_ DI_torque1Counter : 13|3@1+ (1,0) [0|0] "" NEO
SG_ DI_torqueMotor : 16|13@1- (0.25,0) [-750|750] "Nm" NEO
SG_ DI_soptState : 29|3@1+ (1,0) [0|0] "" NEO
SG_ DI_motorRPM : 32|16@1- (1,0) [-17000|17000] "RPM" NEO
SG_ DI_pedalPos : 48|8@1+ (0.4,0) [0|100] "%" NEO
SG_ DI_torque1Checksum : 56|8@1+ (1,0) [0|0] "" NEO
BO_ 280 DI_torque2: 6 DI
SG_ DI_torqueEstimate : 0|12@1- (0.5,0) [-750|750] "Nm" NEO
SG_ DI_gear : 12|3@1+ (1,0) [0|0] "" NEO
SG_ DI_brakePedal : 15|1@1+ (1,0) [0|0] "" NEO
SG_ DI_vehicleSpeed : 16|12@1+ (0.05,-25) [-25|179.75] "MPH" NEO
SG_ DI_gearRequest : 28|3@1+ (1,0) [0|0] "" NEO
SG_ DI_torqueInterfaceFailure : 31|1@1+ (1,0) [0|0] "" NEO
SG_ DI_torque2Counter : 32|4@1+ (1,0) [0|0] "" NEO
SG_ DI_brakePedalState : 36|2@1+ (1,0) [0|0] "" NEO
SG_ DI_epbParkRequest : 38|1@1+ (1,0) [0|0] "" NEO
SG_ DI_epbInterfaceReady : 39|1@1+ (1,0) [0|0] "" NEO
SG_ DI_torque2Checksum : 40|8@1+ (1,0) [0|0] "" NEO
BO_ 309 ESP_135h: 5 ESP
SG_ ESP_135hChecksum : 16|8@1+ (1,0) [0|255] "" NEO
SG_ ESP_135hCounter : 12|4@1+ (1,0) [0|15] "" NEO
SG_ ESP_absBrakeEvent : 5|1@1+ (1,0) [2|-1] "" NEO
SG_ ESP_brakeDiscWipingActive : 3|1@1+ (1,0) [2|-1] "" NEO
SG_ ESP_brakeLamp : 4|1@1+ (1,0) [2|-1] "" NEO
SG_ ESP_espFaultLamp : 1|1@1+ (1,0) [2|-1] "" NEO
SG_ ESP_espLampFlash : 0|1@1+ (1,0) [2|-1] "" NEO
SG_ ESP_hillStartAssistActive : 6|2@1+ (1,0) [4|-1] "" NEO
SG_ ESP_messagePumpService : 31|1@1+ (1,0) [0|1] "" NEO
SG_ ESP_messagePumpFailure : 30|1@1+ (1,0) [0|1] "" NEO
SG_ ESP_messageEBDFailure : 29|1@1+ (1,0) [0|1] "" NEO
SG_ ESP_absFaultLamp : 28|1@1+ (1,0) [2|-1] "" NEO
SG_ ESP_tcDisabledByFault : 27|1@1+ (1,0) [0|1] "" NEO
SG_ ESP_messageDynoModeActive : 26|1@1+ (1,0) [0|1] "" NEO
SG_ ESP_hydraulicBoostEnabled : 25|1@1+ (1,0) [0|1] "" NEO
SG_ ESP_espOffLamp : 24|1@1+ (1,0) [2|-1] "" NEO
SG_ ESP_stabilityControlSts : 9|3@1+ (1,0) [6|7] "" NEO
SG_ ESP_tcLampFlash : 2|1@1+ (1,0) [2|-1] "" NEO
SG_ ESP_tcOffLamp : 8|1@1+ (1,0) [0|1] "" NEO
BO_ 792 GTW_carState: 8 GTW
SG_ BOOT_STATE : 40|2@1+ (1,0) [4|-1] "" NEO
SG_ CERRD : 0|1@1+ (1,0) [2|-1] "" NEO
SG_ DAY : 35|5@1+ (1,0) [2|31] "" NEO
SG_ DOOR_STATE_FL : 10|2@1+ (1,0) [4|-1] "" NEO
SG_ DOOR_STATE_FR : 8|2@1+ (1,0) [4|-1] "" NEO
SG_ DOOR_STATE_FrontTrunk : 52|2@1+ (1,0) [4|-1] "" NEO
SG_ DOOR_STATE_RL : 16|2@1+ (1,0) [4|-1] "" NEO
SG_ DOOR_STATE_RR : 25|2@1+ (1,0) [4|-1] "" NEO
SG_ GTW_updateInProgress : 54|2@1+ (1,0) [4|-1] "" NEO
SG_ Hour : 27|5@1+ (1,0) [0|29] "h" NEO
SG_ MCU_factoryMode : 51|1@1+ (1,0) [2|-1] "" NEO
SG_ MCU_transportModeOn : 50|1@1+ (1,0) [1|1] "" NEO
SG_ MINUTE : 42|6@1+ (1,0) [0|61] "min" NEO
SG_ MONTH : 12|4@1+ (1,0) [0|14] "Month" NEO
SG_ SECOND : 18|6@1+ (1,0) [0|61] "s" NEO
SG_ YEAR : 1|7@1+ (1,2000) [2000|2125] "Year" NEO
BO_ 872 DI_state: 8 DI
SG_ DI_aebState : 44|3@1+ (1,0) [5|6] "" NEO
SG_ DI_analogSpeed : 20|12@1+ (0.10,0) [0|409.40] "speed" NEO
SG_ DI_cruiseSet : 39|9@1+ (0.50,0) [0|255.50] "speed" NEO
SG_ DI_cruiseState : 8|4@1+ (1,0) [8|15] "" NEO
SG_ DI_digitalSpeed : 48|8@1+ (1,0) [0|254] "" NEO
SG_ DI_driveReady : 0|1@1+ (1,0) [0|1] "" NEO
SG_ DI_immobilizerState : 25|3@1+ (1,0) [7|7] "" NEO
SG_ DI_proximity : 1|1@1+ (1,0) [0|1] "" NEO
SG_ DI_regenLight : 15|1@1+ (1,0) [0|1] "" NEO
SG_ DI_speedUnits : 24|1@1+ (1,0) [2|-1] "" NEO
SG_ DI_state : 12|3@1+ (1,0) [5|7] "" NEO
SG_ DI_stateChecksum : 56|8@1+ (1,0) [0|255] "" NEO
SG_ DI_stateCounter : 40|4@1+ (1,0) [0|15] "" NEO
SG_ DI_systemState : 5|3@1+ (1,0) [5|7] "" NEO
SG_ DI_vehicleHoldState : 2|3@1+ (1,0) [8|-1] "" NEO
BO_ 109 SBW_RQ_SCCM: 4 STW
SG_ StW_Sw_Stat3 : 0|3@1+ (1,0) [0|0] "" NEO
SG_ MsgTxmtId : 6|2@1+ (1,0) [0|0] "" NEO
SG_ TSL_RND_Posn_StW : 8|4@1+ (1,0) [0|0] "" NEO
SG_ TSL_P_Psd_StW : 12|2@1+ (1,0) [0|0] "" NEO
SG_ MC_SBW_RQ_SCCM : 20|4@1+ (1,0) [0|15] "" NEO
SG_ CRC_SBW_RQ_SCCM : 24|8@1+ (1,0) [0|0] "" NEO
BO_ 69 STW_ACTN_RQ: 8 STW
SG_ SpdCtrlLvr_Stat : 0|6@1+ (1,0) [0|0] "" NEO
SG_ VSL_Enbl_Rq : 6|1@1+ (1,0) [0|0] "" NEO
SG_ SpdCtrlLvrStat_Inv : 7|1@1+ (1,0) [0|0] "" NEO
SG_ DTR_Dist_Rq : 8|8@1+ (1,0) [0|200] "" NEO
SG_ TurnIndLvr_Stat : 16|2@1+ (1,0) [0|0] "" NEO
SG_ HiBmLvr_Stat : 18|2@1+ (1,0) [0|0] "" NEO
SG_ WprWashSw_Psd : 20|2@1+ (1,0) [0|0] "" NEO
SG_ WprWash_R_Sw_Posn_V2 : 22|2@1+ (1,0) [0|0] "" NEO
SG_ StW_Lvr_Stat : 24|3@1+ (1,0) [0|0] "" NEO
SG_ StW_Cond_Flt : 27|1@1+ (1,0) [0|0] "" NEO
SG_ StW_Cond_Psd : 28|2@1+ (1,0) [0|0] "" NEO
SG_ HrnSw_Psd : 30|2@1+ (1,0) [0|0] "" NEO
SG_ StW_Sw00_Psd : 32|1@1+ (1,0) [0|0] "" NEO
SG_ StW_Sw01_Psd : 33|1@1+ (1,0) [0|0] "" NEO
SG_ StW_Sw02_Psd : 34|1@1+ (1,0) [0|0] "" NEO
SG_ StW_Sw03_Psd : 35|1@1+ (1,0) [0|0] "" NEO
SG_ StW_Sw04_Psd : 36|1@1+ (1,0) [0|0] "" NEO
SG_ StW_Sw05_Psd : 37|1@1+ (1,0) [0|0] "" NEO
SG_ StW_Sw06_Psd : 38|1@1+ (1,0) [0|0] "" NEO
SG_ StW_Sw07_Psd : 39|1@1+ (1,0) [0|0] "" NEO
SG_ StW_Sw08_Psd : 40|1@1+ (1,0) [0|0] "" NEO
SG_ StW_Sw09_Psd : 41|1@1+ (1,0) [0|0] "" NEO
SG_ StW_Sw10_Psd : 42|1@1+ (1,0) [0|0] "" NEO
SG_ StW_Sw11_Psd : 43|1@1+ (1,0) [0|0] "" NEO
SG_ StW_Sw12_Psd : 44|1@1+ (1,0) [0|0] "" NEO
SG_ StW_Sw13_Psd : 45|1@1+ (1,0) [0|0] "" NEO
SG_ StW_Sw14_Psd : 46|1@1+ (1,0) [0|0] "" NEO
SG_ StW_Sw15_Psd : 47|1@1+ (1,0) [0|0] "" NEO
SG_ WprSw6Posn : 48|3@1+ (1,0) [0|0] "" NEO
SG_ MC_STW_ACTN_RQ : 52|4@1+ (1,0) [0|15] "" NEO
SG_ CRC_STW_ACTN_RQ : 56|8@1+ (1,0) [0|0] "" NEO
BO_ 643 BODY_R1: 8 GTW
SG_ AirTemp_Insd : 40|8@1+ (0.25,0) [0|63.5] "C" NEO
SG_ AirTemp_Outsd : 56|8@1+ (0.5,-40) [-40|86.5] "C" NEO
SG_ Bckl_Sw_RL_Stat_SAM_R : 54|2@1+ (1,0) [4|-1] "" NEO
SG_ Bckl_Sw_RM_Stat_SAM_R : 50|2@1+ (1,0) [4|-1] "" NEO
SG_ Bckl_Sw_RR_Stat_SAM_R : 52|2@1+ (1,0) [4|-1] "" NEO
SG_ DL_RLtch_Stat : 14|2@1+ (1,0) [4|-1] "" NEO
SG_ DrRLtch_FL_Stat : 6|2@1+ (1,0) [4|-1] "" NEO
SG_ DrRLtch_FR_Stat : 4|2@1+ (1,0) [4|-1] "" NEO
SG_ DrRLtch_RL_Stat : 2|2@1+ (1,0) [4|-1] "" NEO
SG_ DrRLtch_RR_Stat : 0|2@1+ (1,0) [4|-1] "" NEO
SG_ EngHd_Stat : 12|2@1+ (1,0) [4|-1] "" NEO
SG_ LoBm_On_Rq : 39|1@1+ (1,0) [0|1] "" NEO
SG_ HiBm_On : 38|1@1+ (1,0) [0|1] "" NEO
SG_ Hrn_On : 29|1@1+ (1,0) [0|1] "" NEO
SG_ IrLmp_D_Lt_Flt : 37|1@1+ (1,0) [0|1] "" NEO
SG_ IrLmp_P_Rt_Flt : 36|1@1+ (1,0) [0|1] "" NEO
SG_ LgtSens_Twlgt : 21|3@1+ (1,0) [0|7] "Steps" NEO
SG_ LgtSens_SNA : 20|1@1+ (1,0) [0|1] "" NEO
SG_ LgtSens_Tunnel : 19|1@1+ (1,0) [0|1] "" NEO
SG_ LgtSens_Flt : 18|1@1+ (1,0) [0|1] "" NEO
SG_ LgtSens_Night : 17|1@1+ (1,0) [2|-1] "" NEO
SG_ ADL_LoBm_On_Rq : 16|1@1+ (1,0) [0|1] "" NEO
SG_ LoBm_D_Lt_Flt : 35|1@1+ (1,0) [0|1] "" NEO
SG_ LoBm_P_Rt_Flt : 34|1@1+ (1,0) [0|1] "" NEO
SG_ MPkBrk_Stat : 27|1@1+ (1,0) [2|-1] "" NEO
SG_ RevGr_Engg : 32|2@1+ (1,0) [4|-1] "" NEO
SG_ StW_Cond_Stat : 48|2@1+ (1,0) [4|-1] "" NEO
SG_ Term54_Actv : 28|1@1+ (1,0) [0|1] "" NEO
SG_ Trlr_Stat : 30|2@1+ (1,0) [4|-1] "" NEO
SG_ VTA_Alm_Actv : 10|1@1+ (1,0) [0|1] "" NEO
SG_ WprOutsdPkPosn : 26|1@1+ (1,0) [0|1] "" NEO
BO_ 760 MCU_gpsVehicleSpeed: 8 MCU
SG_ MCU_gpsHDOP : 0|8@1+ (0.10,0) [0|25.50] "1" NEO
SG_ MCU_gpsVehicleHeading : 8|16@1+ (0.007810,0) [0|511.828350] "deg" NEO
SG_ MCU_gpsVehicleSpeed : 24|16@1+ (0.003910,0) [0|256.241850] "km/hr" NEO
SG_ MCU_mppSpeedLimit : 51|5@1+ (5,0) [0|155] "kph/mph" NEO
SG_ MCU_speedLimitUnits : 41|1@1+ (1,0) [2|-1] "" NEO
SG_ MCU_userSpeedOffset : 42|6@1+ (1,-30) [-30|33] "kph/mph" NEO
SG_ MCU_userSpeedOffsetUnits : 40|1@1+ (1,0) [2|-1] "" NEO
BO_ 904 MCU_clusterBacklightRequest: 3 NEO
SG_ MCU_clusterBacklightOn : 7|1@1+ (1,0) [0|1] "" NEO
SG_ MCU_clusterBrightnessLevel : 8|8@1+ (0.5,0) [0|127.5] "%" NEO
SG_ MCU_clusterReadyForDrive : 6|1@1+ (1,0) [2|-1] "" NEO
SG_ MCU_clusterReadyForPowerOff : 5|1@1+ (1,0) [0|1] "" NEO
BO_ 984 MCU_locationStatus: 8 MCU
SG_ MCU_gpsAccuracy : 56|7@1+ (0.200000003,0) [0|25.200000378] "m" NEO
SG_ MCU_latitude : 0|28@1- (0.000001,0) [-134.21772759734682|134.21772659734683] "deg" NEO
SG_ MCU_longitude : 28|28@1- (0.000001,0) [-268.43545519469365|268.43545419469365] "deg" NEO
BO_ 840 GTW_status: 8 GTW
SG_ GTW_accGoingDown : 1|1@1+ (1,0) [0|1] "" NEO
SG_ GTW_accRailReq : 15|1@1+ (1,0) [0|1] "" NEO
SG_ GTW_brakePressed : 6|1@1+ (1,0) [0|1] "" NEO
SG_ GTW_driveGoingDown : 0|1@1+ (1,0) [0|1] "" NEO
SG_ GTW_driveRailReq : 7|1@1+ (1,0) [0|1] "" NEO
SG_ GTW_driverIsLeaving : 2|1@1+ (1,0) [0|1] "" NEO
SG_ GTW_driverPresent : 5|1@1+ (1,0) [0|1] "" NEO
SG_ GTW_hvacGoingDown : 12|1@1+ (1,0) [0|1] "" NEO
SG_ GTW_hvacRailReq : 14|1@1+ (1,0) [0|1] "" NEO
SG_ GTW_icPowerOff : 3|1@1+ (1,0) [0|1] "" NEO
SG_ GTW_notEnough12VForDrive : 4|1@1+ (1,0) [0|1] "" NEO
SG_ GTW_preconditionRequest : 13|1@1+ (1,0) [0|1] "" NEO
SG_ GTW_statusChecksum : 56|8@1+ (1,0) [0|255] "" NEO
SG_ GTW_statusCounter : 52|4@1+ (1,0) [0|15] "" NEO
VAL_ 3 StW_Angl 16383 "SNA" ;
VAL_ 3 StW_AnglSens_Id 2 "MUST" 0 "PSBL" 1 "SELF" ;
VAL_ 3 StW_AnglSens_Stat 2 "ERR" 3 "ERR_INI" 1 "INI" 0 "OK" ;
VAL_ 3 StW_AnglSpd 16383 "SNA" ;
VAL_ 14 StW_AnglHP 16383 "SNA" ;
VAL_ 14 StW_AnglHP_Spd 16383 "SNA" ;
VAL_ 14 StW_AnglHP_Sens_Stat 3 "SNA" 2 "ERR" 1 "INI" 0 "OK" ;
VAL_ 14 StW_AnglHP_Sens_Id 3 "SNA" 2 "KOSTAL" 1 "DELPHI" 0 "TEST" ;
VAL_ 69 SpdCtrlLvr_Stat 32 "DN_1ST" 16 "UP_1ST" 8 "DN_2ND" 4 "UP_2ND" 2 "RWD" 1 "FWD" 0 "IDLE" ;
VAL_ 69 DTR_Dist_Rq 255 "SNA" 200 "ACC_DIST_7" 166 "ACC_DIST_6" 133 "ACC_DIST_5" 100 "ACC_DIST_4" 66 "ACC_DIST_3" 33 "ACC_DIST_2" 0 "ACC_DIST_1" ;
VAL_ 69 TurnIndLvr_Stat 3 "SNA" 2 "RIGHT" 1 "LEFT" 0 "IDLE" ;
VAL_ 69 HiBmLvr_Stat 3 "SNA" 2 "HIBM_FLSH_ON_PSD" 1 "HIBM_ON_PSD" 0 "IDLE" ;
VAL_ 69 WprWashSw_Psd 3 "SNA" 2 "WASH" 1 "TIPWIPE" 0 "NPSD" ;
VAL_ 69 WprWash_R_Sw_Posn_V2 3 "SNA" 2 "WASH" 1 "INTERVAL" 0 "OFF" ;
VAL_ 69 StW_Lvr_Stat 4 "STW_BACK" 3 "STW_FWD" 2 "STW_DOWN" 1 "STW_UP" 0 "NPSD" ;
VAL_ 69 StW_Cond_Psd 3 "SNA" 2 "DOWN" 1 "UP" 0 "NPSD" ;
VAL_ 69 HrnSw_Psd 3 "SNA" 2 "NDEF2" 1 "PSD" 0 "NPSD" ;
VAL_ 69 StW_Sw00_Psd 1 "PRESSED" 0 "NOT_PRESSED_SNA" ;
VAL_ 69 StW_Sw01_Psd 1 "PRESSED" 0 "NOT_PRESSED_SNA" ;
VAL_ 69 StW_Sw03_Psd 1 "PRESSED" 0 "NOT_PRESSED_SNA" ;
VAL_ 69 StW_Sw04_Psd 1 "PRESSED" 0 "NOT_PRESSED_SNA" ;
VAL_ 69 WprSw6Posn 7 "SNA" 6 "STAGE2" 5 "STAGE1" 4 "INTERVAL4" 3 "INTERVAL3" 2 "INTERVAL2" 1 "INTERVAL1" 0 "OFF" ;VAL_ 257 GTW_epasControlType 0 "WITHOUT" 1 "WITH_ANGLE" 3 "WITH_BOTH" 2 "WITH_TORQUE" ;
VAL_ 109 StW_Sw_Stat3 7 "SNA" 6 "NDEF6" 5 "NDEF5" 4 "NDEF4" 3 "PLUS_MINUS" 2 "MINUS" 1 "PLUS" 0 "NPSD" ;
VAL_ 109 MsgTxmtId 3 "NDEF3" 2 "NDEF2" 1 "SCCM" 0 "EWM" ;
VAL_ 109 TSL_RND_Posn_StW 15 "SNA" 8 "D" 6 "INI" 4 "N_DOWN" 2 "N_UP" 1 "R" 0 "IDLE" ;
VAL_ 109 TSL_P_Psd_StW 3 "SNA" 2 "INI" 1 "PSD" 0 "IDLE" ;
VAL_ 257 GTW_epasEmergencyOn 1 "EMERGENCY_POWER" 0 "NONE" ;
VAL_ 257 GTW_epasLDWEnabled 1 "ALLOWED" 0 "INHIBITED" ;
VAL_ 257 GTW_epasPowerMode 0 "DRIVE_OFF" 1 "DRIVE_ON" 3 "LOAD_SHED" 2 "SHUTTING_DOWN" 15 "SNA" ;
VAL_ 257 GTW_epasTuneRequest 1 "DM_COMFORT" 3 "DM_SPORT" 2 "DM_STANDARD" 0 "FAIL_SAFE_DEFAULT" 4 "RWD_COMFORT" 6 "RWD_SPORT" 5 "RWD_STANDARD" 7 "SNA" ;
VAL_ 264 DI_torqueDriver -4096 "SNA" ;
VAL_ 264 DI_torqueMotor -4096 "SNA" ;
VAL_ 264 DI_soptState 7 "SOPT_TEST_SNA" 4 "SOPT_TEST_NOT_RUN" 3 "SOPT_TEST_PASSED" 2 "SOPT_TEST_FAILED" 1 "SOPT_TEST_IN_PROGRESS" 0 "SOPT_PRE_TEST" ;
VAL_ 264 DI_motorRPM -32768 "SNA" ;
VAL_ 264 DI_pedalPos 255 "SNA" ;
VAL_ 280 DI_torqueEstimate -2048 "SNA" ;
VAL_ 280 DI_gear 7 "DI_GEAR_SNA" 4 "DI_GEAR_D" 3 "DI_GEAR_N" 2 "DI_GEAR_R" 1 "DI_GEAR_P" 0 "DI_GEAR_INVALID" ;
VAL_ 280 DI_brakePedal 1 "Applied" 0 "Not_applied" ;
VAL_ 280 DI_vehicleSpeed 4095 "SNA" ;
VAL_ 280 DI_gearRequest 7 "DI_GEAR_SNA" 4 "DI_GEAR_D" 3 "DI_GEAR_N" 2 "DI_GEAR_R" 1 "DI_GEAR_P" 0 "DI_GEAR_INVALID" ;
VAL_ 280 DI_torqueInterfaceFailure 1 "TORQUE_INTERFACE_FAILED" 0 "TORQUE_INTERFACE_NORMAL" ;
VAL_ 280 DI_brakePedalState 3 "SNA" 2 "INVALID" 1 "ON" 0 "OFF" ;
VAL_ 280 DI_epbParkRequest 1 "Park_requested" 0 "No_request" ;
VAL_ 280 DI_epbInterfaceReady 1 "EPB_INTERFACE_READY" 0 "EPB_INTERFACE_NOT_READY" ;
VAL_ 309 ESP_absBrakeEvent 1 "ACTIVE" 0 "NOT_ACTIVE" ;
VAL_ 309 ESP_brakeDiscWipingActive 1 "ACTIVE" 0 "INACTIVE" ;
VAL_ 309 ESP_brakeLamp 0 "OFF" 1 "ON" ;
VAL_ 309 ESP_espFaultLamp 0 "OFF" 1 "ON" ;
VAL_ 309 ESP_espLampFlash 1 "FLASH" 0 "OFF" ;
VAL_ 309 ESP_hillStartAssistActive 1 "ACTIVE" 0 "INACTIVE" 2 "NOT_AVAILABLE" 3 "SNA" ;
VAL_ 309 ESP_absFaultLamp 0 "OFF" 1 "ON" ;
VAL_ 309 ESP_espOffLamp 0 "OFF" 1 "ON" ;
VAL_ 309 ESP_stabilityControlSts 2 "ENGAGED" 3 "FAULTED" 5 "INIT" 4 "NOT_CONFIGURED" 0 "OFF" 1 "ON" ;
VAL_ 309 ESP_tcLampFlash 1 "FLASH" 0 "OFF" ;
VAL_ 760 MCU_speedLimitUnits 1 "KPH" 0 "MPH" ;
VAL_ 760 MCU_userSpeedOffsetUnits 1 "KPH" 0 "MPH" ;
VAL_ 643 AirTemp_Insd 255 "SNA" ;
VAL_ 643 AirTemp_Outsd 254 "INIT" 255 "SNA" ;
VAL_ 643 Bckl_Sw_RL_Stat_SAM_R 2 "FLT" 1 "NOT" 0 "OK" 3 "SNA" ;
VAL_ 643 Bckl_Sw_RM_Stat_SAM_R 2 "FLT" 1 "NOT" 0 "OK" 3 "SNA" ;
VAL_ 643 Bckl_Sw_RR_Stat_SAM_R 2 "FLT" 1 "NOT" 0 "OK" 3 "SNA" ;
VAL_ 643 DL_RLtch_Stat 1 "CLS" 0 "NDEF0" 2 "OPN" 3 "SNA" ;
VAL_ 643 DrRLtch_FL_Stat 1 "CLS" 0 "NDEF0" 2 "OPN" 3 "SNA" ;
VAL_ 643 DrRLtch_FR_Stat 1 "CLS" 0 "NDEF0" 2 "OPN" 3 "SNA" ;
VAL_ 643 DrRLtch_RL_Stat 1 "CLS" 0 "NDEF0" 2 "OPN" 3 "SNA" ;
VAL_ 643 DrRLtch_RR_Stat 1 "CLS" 0 "NDEF0" 2 "OPN" 3 "SNA" ;
VAL_ 643 EngHd_Stat 1 "CLS" 0 "NDEF0" 2 "OPN" 3 "SNA" ;
VAL_ 643 LgtSens_Night 0 "DAY" 1 "NIGHT" ;
VAL_ 643 MPkBrk_Stat 1 "ENGG" 0 "RELS" ;
VAL_ 643 RevGr_Engg 0 "DISENGG" 1 "ENGG" 2 "NDEF2" 3 "SNA" ;
VAL_ 643 StW_Cond_Stat 3 "BLINK" 1 "NDEF1" 0 "OFF" 2 "ON" ;
VAL_ 643 Trlr_Stat 2 "NDEF2" 0 "NONE" 1 "OK" 3 "SNA" ;
VAL_ 792 BOOT_STATE 2 "Init" 3 "SNA" 0 "closed" 1 "open" ;
VAL_ 792 CERRD 1 "CAN error detect" 0 "no Can error detected" ;
VAL_ 792 DAY 1 "Init" 0 "SNA" ;
VAL_ 792 DOOR_STATE_FL 2 "Init" 3 "SNA" 0 "closed" 1 "open" ;
VAL_ 792 DOOR_STATE_FR 2 "Init" 3 "SNA" 0 "closed" 1 "open" ;
VAL_ 792 DOOR_STATE_FrontTrunk 2 "Init" 3 "SNA" 0 "closed" 1 "open" ;
VAL_ 792 DOOR_STATE_RL 2 "Init" 3 "SNA" 0 "closed" 1 "open" ;
VAL_ 792 DOOR_STATE_RR 2 "Init" 3 "SNA" 0 "closed" 1 "open" ;
VAL_ 792 GTW_updateInProgress 1 "IN_PROGRESS" 2 "IN_PROGRESS_NOT_USED" 3 "IN_PROGRESS_SNA" 0 "NOT_IN_PROGRESS" ;
VAL_ 792 Hour 30 "Init" 31 "SNA" ;
VAL_ 792 MCU_factoryMode 1 "FACTORY_MODE" 0 "NORMAL_MODE" ;
VAL_ 792 MCU_transportModeOn 0 "NORMAL_MODE" ;
VAL_ 792 MINUTE 62 "Init" 63 "SNA" ;
VAL_ 792 MONTH 1 "Init" 15 "SNA" ;
VAL_ 792 SECOND 62 "Init" 63 "SNA" ;
VAL_ 792 YEAR 126 "Init" 127 "SNA" ;
VAL_ 872 DI_aebState 2 "ENABLED" 4 "FAULT" 7 "SNA" 1 "STANDBY" 3 "STANDSTILL" 0 "UNAVAILABLE" ;
VAL_ 872 DI_analogSpeed 4095 "SNA" ;
VAL_ 872 DI_cruiseState 2 "ENABLED" 5 "FAULT" 0 "OFF" 4 "OVERRIDE" 7 "PRE_CANCEL" 6 "PRE_FAULT" 1 "STANDBY" 3 "STANDSTILL" ;
VAL_ 872 DI_digitalSpeed 255 "SNA" ;
VAL_ 872 DI_immobilizerState 2 "AUTHENTICATING" 3 "DISARMED" 6 "FAULT" 4 "IDLE" 0 "INIT_SNA" 1 "REQUEST" 5 "RESET" ;
VAL_ 872 DI_speedUnits 1 "KPH" 0 "MPH" ;
VAL_ 872 DI_state 3 "ABORT" 4 "ENABLE" 2 "FAULT" 1 "STANDBY" 0 "UNAVAILABLE" ;
VAL_ 872 DI_systemState 3 "ABORT" 4 "ENABLE" 2 "FAULT" 1 "STANDBY" 0 "UNAVAILABLE" ;
VAL_ 872 DI_vehicleHoldState 2 "BLEND_IN" 4 "BLEND_OUT" 6 "FAULT" 7 "INIT" 5 "PARK" 1 "STANDBY" 3 "STANDSTILL" 0 "UNAVAILABLE" ;
VAL_ 880 EPAS_currentTuneMode 1 "DM_COMFORT" 3 "DM_SPORT" 2 "DM_STANDARD" 0 "FAIL_SAFE_DEFAULT" 4 "RWD_COMFORT" 6 "RWD_SPORT" 5 "RWD_STANDARD" 7 "UNAVAILABLE" ;
VAL_ 880 EPAS_eacErrorCode 14 "EAC_ERROR_EPB_INHIBIT" 3 "EAC_ERROR_HANDS_ON" 7 "EAC_ERROR_HIGH_ANGLE_RATE_REQ" 9 "EAC_ERROR_HIGH_ANGLE_RATE_SAFETY" 6 "EAC_ERROR_HIGH_ANGLE_REQ" 8 "EAC_ERROR_HIGH_ANGLE_SAFETY" 10 "EAC_ERROR_HIGH_MMOT_SAFETY" 11 "EAC_ERROR_HIGH_TORSION_SAFETY" 0 "EAC_ERROR_IDLE" 12 "EAC_ERROR_LOW_ASSIST" 2 "EAC_ERROR_MAX_SPEED" 1 "EAC_ERROR_MIN_SPEED" 13 "EAC_ERROR_PINION_VEL_DIFF" 4 "EAC_ERROR_TMP_FAULT" 5 "EAR_ERROR_MAX_STEER_DELTA" 15 "SNA" ;
VAL_ 880 EPAS_eacStatus 2 "EAC_ACTIVE" 1 "EAC_AVAILABLE" 3 "EAC_FAULT" 0 "EAC_INHIBITED" 4 "SNA" ;
VAL_ 880 EPAS_handsOnLevel 0 "0" 1 "1" 2 "2" 3 "3" ;
VAL_ 880 EPAS_steeringFault 1 "FAULT" 0 "NO_FAULT" ;
VAL_ 880 EPAS_steeringRackForce 1022 "NOT_IN_SPEC" 1023 "SNA" ;
VAL_ 880 EPAS_steeringReduced 0 "NORMAL_ASSIST" 1 "REDUCED_ASSIST" ;
VAL_ 880 EPAS_torsionBarTorque 0 "SEE_SPECIFICATION" 4095 "SNA" 4094 "UNDEFINABLE_DATA" ;
VAL_ 904 MCU_clusterReadyForDrive 0 "NO_SNA" 1 "YES" ;
VAL_ 1160 DAS_steeringAngleRequest 16384 "ZERO_ANGLE" ;
VAL_ 1160 DAS_steeringControlType 1 "ANGLE_CONTROL" 3 "DISABLED" 0 "NONE" 2 "RESERVED" ;
VAL_ 1160 DAS_steeringHapticRequest 1 "ACTIVE" 0 "IDLE" ;

1
opendbc Submodule

Submodule opendbc added at b77861eb00

2
panda

Submodule panda updated: 49c1e9c3da...5409c51041

1
pyextra Submodule

Submodule pyextra added at e0738376db

View File

@@ -9,4 +9,6 @@ requests==2.10.0
setproctitle==1.1.10
simplejson==3.8.2
pyyaml==3.12
cffi==1.7.0
enum34==1.1.1
-e git+https://github.com/commaai/le_python.git#egg=Logentries

1
selfdrive/boardd/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
boardd

View File

@@ -31,11 +31,16 @@ pthread_mutex_t usb_lock;
bool spoofing_started = false;
bool fake_send = false;
bool loopback_can = false;
// double the FIFO size
#define RECV_SIZE (0x1000)
#define TIMEOUT 0
#define SAFETY_NOOUTPUT 0x0000
#define SAFETY_HONDA 0x0001
#define SAFETY_ALLOUTPUT 0x1337
bool usb_connect() {
int err;
@@ -48,19 +53,36 @@ bool usb_connect() {
err = libusb_claim_interface(dev_handle, 0);
if (err != 0) { return false; }
if (loopback_can) {
libusb_control_transfer(dev_handle, 0xc0, 0xe5, 1, 0, NULL, 0, TIMEOUT);
}
// power off ESP
libusb_control_transfer(dev_handle, 0xc0, 0xd9, 0, 0, NULL, 0, TIMEOUT);
// forward CAN1 to CAN3...soon
//libusb_control_transfer(dev_handle, 0xc0, 0xdd, 1, 2, NULL, 0, TIMEOUT);
// set UART modes for Honda Accord
for (int uart = 2; uart <= 3; uart++) {
/*for (int uart = 2; uart <= 3; uart++) {
// 9600 baud
libusb_control_transfer(dev_handle, 0xc0, 0xe1, uart, 9600, NULL, 0, TIMEOUT);
libusb_control_transfer(dev_handle, 0x40, 0xe1, uart, 9600, NULL, 0, TIMEOUT);
// even parity
libusb_control_transfer(dev_handle, 0xc0, 0xe2, uart, 1, NULL, 0, TIMEOUT);
libusb_control_transfer(dev_handle, 0x40, 0xe2, uart, 1, NULL, 0, TIMEOUT);
// callback 1
libusb_control_transfer(dev_handle, 0xc0, 0xe3, uart, 1, NULL, 0, TIMEOUT);
libusb_control_transfer(dev_handle, 0x40, 0xe3, uart, 1, NULL, 0, TIMEOUT);
}
// TODO: Boardd should be able to set the baud rate
int baud = 500000;
libusb_control_transfer(dev_handle, 0x40, 0xde, 0, 0,
(unsigned char *)&baud, sizeof(baud), TIMEOUT); // CAN1
libusb_control_transfer(dev_handle, 0x40, 0xde, 1, 0,
(unsigned char *)&baud, sizeof(baud), TIMEOUT); // CAN2*/
// TODO: Boardd should be able to be told which safety model to use
libusb_control_transfer(dev_handle, 0x40, 0xdc, SAFETY_HONDA, 0, NULL, 0, TIMEOUT);
return true;
}
@@ -87,7 +109,7 @@ void can_recv(void *s) {
// do recv
pthread_mutex_lock(&usb_lock);
do {
err = libusb_bulk_transfer(dev_handle, 0x81, (uint8_t*)data, RECV_SIZE, &recv, TIMEOUT);
if (err != 0) { handle_usb_issue(err, __func__); }
@@ -124,13 +146,13 @@ void can_recv(void *s) {
canData[i].setBusTime(data[i*4+1] >> 16);
int len = data[i*4+1]&0xF;
canData[i].setDat(kj::arrayPtr((uint8_t*)&data[i*4+2], len));
canData[i].setSrc((data[i*4+1] >> 4) & 0xf);
canData[i].setSrc((data[i*4+1] >> 4) & 0xff);
}
// send to can
auto words = capnp::messageToFlatArray(msg);
auto bytes = words.asBytes();
zmq_send(s, bytes.begin(), bytes.size(), 0);
zmq_send(s, bytes.begin(), bytes.size(), 0);
}
void can_health(void *s) {
@@ -178,7 +200,7 @@ void can_health(void *s) {
// send to health
auto words = capnp::messageToFlatArray(msg);
auto bytes = words.asBytes();
zmq_send(s, bytes.begin(), bytes.size(), 0);
zmq_send(s, bytes.begin(), bytes.size(), 0);
}
@@ -313,6 +335,10 @@ int main() {
fake_send = true;
}
if(getenv("BOARDD_LOOPBACK")){
loopback_can = true;
}
// init libusb
err = libusb_init(&ctx);
assert(err == 0);
@@ -354,4 +380,3 @@ int main() {
libusb_close(dev_handle);
libusb_exit(ctx);
}

View File

@@ -18,6 +18,10 @@ except Exception:
# TODO: rewrite in C to save CPU
SAFETY_NOOUTPUT = 0
SAFETY_HONDA = 1
SAFETY_ALLOUTPUT = 0x1337
# *** serialization functions ***
def can_list_to_can_capnp(can_msgs, msgtype='can'):
dat = messaging.new_message()
@@ -85,6 +89,7 @@ def can_recv():
def can_init():
global handle, context
handle = None
cloudlog.info("attempting can init")
context = usb1.USBContext()
@@ -94,6 +99,7 @@ def can_init():
if device.getVendorID() == 0xbbaa and device.getProductID() == 0xddcc:
handle = device.open()
handle.claimInterface(0)
handle.controlWrite(0x40, 0xdc, SAFETY_HONDA, 0, b'')
if handle is None:
print "CAN NOT FOUND"
@@ -190,4 +196,3 @@ def main(gctx=None):
if __name__ == "__main__":
main()

72
selfdrive/can/Makefile Normal file
View File

@@ -0,0 +1,72 @@
CC = clang
CXX = clang++
PHONELIBS := ../../phonelibs
UNAME_S := $(shell uname -s)
UNAME_M := $(shell uname -m)
WARN_FLAGS = -Werror=implicit-function-declaration \
-Werror=incompatible-pointer-types \
-Werror=int-conversion \
-Werror=return-type \
-Werror=format-extra-args \
-Wno-deprecated-declarations
CFLAGS = -std=gnu11 -g -fPIC -O2 $(WARN_FLAGS)
CXXFLAGS = -std=c++11 -g -fPIC -O2 $(WARN_FLAGS)
ifeq ($(UNAME_S),Darwin)
CEREAL_LIBS := -L /usr/local/lib -lkj -lcapnp
ZMQ_LIBS = -L/usr/local/lib -lzmq
else ifeq ($(OPTEST),1)
ZMQ_LIBS = -lzmq
CEREAL_LIBS = -lcapnp -lkj
else ifeq ($(UNAME_M),x86_64)
EXTERNAL := ../../external
ZMQ_FLAGS = -I$(EXTERNAL)/zmq/include
ZMQ_LIBS = -L$(EXTERNAL)/zmq/lib -l:libzmq.a
CEREAL_CXXFLAGS := -I$(EXTERNAL)/capnp/include
CEREAL_LIBS := -L$(EXTERNAL)/capnp/lib -l:libcapnp.a -l:libkj.a
else ifeq ($(UNAME_M),aarch64)
ZMQ_FLAGS = -I$(PHONELIBS)/zmq/aarch64/include
ZMQ_LIBS = -L$(PHONELIBS)/zmq/aarch64/lib -l:libzmq.a
endif
OPENDBC_PATH := $(shell python -c 'import opendbc; print opendbc.DBC_PATH')
DBC_SOURCES := $(wildcard $(OPENDBC_PATH)/*.dbc)
DBC_CCS := $(patsubst $(OPENDBC_PATH)/%.dbc,dbc_out/%.cc,$(DBC_SOURCES))
CWD := $(shell pwd)
.PHONY: all
all: libdbc.so
ifeq ($(UNAME_M),aarch64)
include ../common/cereal.mk
endif
# make sure cereal is built
libdbc.so:: ../../cereal/gen/cpp/log.capnp.h
../../cereal/gen/cpp/log.capnp.h:
cd ../../cereal && make
libdbc.so:: parser.cc $(DBC_CCS)
$(CXX) -fPIC -shared -o '$@' $^ \
-I. \
-I../.. \
$(CXXFLAGS) \
$(ZMQ_FLAGS) \
$(ZMQ_LIBS) \
$(CEREAL_CXXFLAGS) \
$(CEREAL_LIBS)
dbc_out/%.cc: $(OPENDBC_PATH)/%.dbc
PYTHONPATH=$(PYTHONPATH):$(CWD)/../../pyextra ./process_dbc.py '$<' '$@'
.PHONY: clean
clean:
rm -rf libdbc.so*
rm -f dbc_out/*.cc

View File

2
selfdrive/can/dbc_out/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
*.cc

View File

View File

@@ -0,0 +1,51 @@
#include <cstdint>
#include "parser_common.h"
namespace {
{% for address, msg_name, sigs in msgs %}
const Signal sigs_{{address}}[] = {
{% for sig in sigs %}
{
{% set b1 = (sig.start_bit//8)*8 + (-sig.start_bit-1) % 8 %}
.name = "{{sig.name}}",
.b1 = {{b1}},
.b2 = {{sig.size}},
.bo = {{64 - (b1 + sig.size)}},
.is_signed = {{"true" if sig.is_signed else "false"}},
.factor = {{sig.factor}},
.offset = {{sig.offset}},
{% if checksum_type == "honda" and sig.name == "CHECKSUM" %}
.type = SignalType::HONDA_CHECKSUM,
{% elif checksum_type == "honda" and sig.name == "COUNTER" %}
.type = SignalType::HONDA_COUNTER,
{% else %}
.type = SignalType::DEFAULT,
{% endif %}
},
{% endfor %}
};
{% endfor %}
const Msg msgs[] = {
{% for address, msg_name, sigs in msgs %}
{% set address_hex = "0x%X" % address %}
{
.name = "{{msg_name}}",
.address = {{address_hex}},
.num_sigs = ARRAYSIZE(sigs_{{address}}),
.sigs = sigs_{{address}},
},
{% endfor %}
};
}
const DBC {{dbc.name}} = {
.name = "{{dbc.name}}",
.num_msgs = ARRAYSIZE(msgs),
.msgs = msgs,
};
dbc_init({{dbc.name}})

441
selfdrive/can/parser.cc Normal file
View File

@@ -0,0 +1,441 @@
#include <cstdio>
#include <cstdint>
#include <cassert>
#include <cstring>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <string>
#include <vector>
#include <algorithm>
#include <unordered_map>
#include <zmq.h>
#include <capnp/serialize.h>
#include "cereal/gen/cpp/log.capnp.h"
#include "parser_common.h"
#define DEBUG(...)
// #define DEBUG printf
#define INFO printf
#define MAX_BAD_COUNTER 5
namespace {
uint64_t read_u64_be(const uint8_t* v) {
return (((uint64_t)v[0] << 56)
| ((uint64_t)v[1] << 48)
| ((uint64_t)v[2] << 40)
| ((uint64_t)v[3] << 32)
| ((uint64_t)v[4] << 24)
| ((uint64_t)v[5] << 16)
| ((uint64_t)v[6] << 8)
| (uint64_t)v[7]);
}
std::vector<const DBC*> g_dbc;
bool honda_checksum(int address, uint64_t d, int l) {
int target = (d >> l) & 0xF;
DEBUG("check checksum %16lx %d", d, l);
// remove checksum from calculation
d &= ~(0xFLL << l);
int s = 0;
while (address > 0) { s += (address & 0xF); address >>= 4; }
while (d > 0) { s += (d & 0xF); d >>= 4; }
s = 8-s;
s &= 0xF;
DEBUG(" %d = %d\n", target, s);
return target == s;
}
struct MessageState {
uint32_t address;
std::vector<Signal> parse_sigs;
std::vector<double> vals;
uint64_t seen;
uint64_t check_threshold;
uint8_t counter;
uint8_t counter_fail;
bool parse(uint64_t sec, uint64_t dat) {
for (int i=0; i < parse_sigs.size(); i++) {
auto& sig = parse_sigs[i];
int64_t tmp = (dat >> sig.bo) & ((1 << sig.b2)-1);
if (sig.is_signed) {
tmp -= (tmp >> (sig.b2-1)) ? (1<<sig.b2) : 0; //signed
}
DEBUG("parse %X %s -> %ld\n", address, sig.name, tmp);
if (sig.type == SignalType::HONDA_CHECKSUM) {
if (!honda_checksum(address, dat, sig.bo)) {
INFO("%X CHECKSUM FAIL\n", address);
return false;
}
} else if (sig.type == SignalType::HONDA_COUNTER) {
if (!honda_update_counter(tmp)) {
return false;
}
}
vals[i] = tmp * sig.factor + sig.offset;
}
seen = sec;
return true;
}
bool honda_update_counter(int64_t v) {
uint8_t old_counter = counter;
counter = v;
if (((old_counter+1) & 3) != v) {
counter_fail += 1;
if (counter_fail > 1) {
INFO("%X COUNTER FAIL %d -- %d vs %d\n", address, counter_fail, old_counter, (int)v);
}
if (counter_fail >= MAX_BAD_COUNTER) {
return false;
}
} else if (counter_fail > 0) {
counter_fail--;
}
return true;
}
};
class CANParser {
public:
CANParser(int abus, const std::string& dbc_name,
const std::vector<MessageParseOptions> &options,
const std::vector<SignalParseOptions> &sigoptions)
: bus(abus) {
// connect to can on 8006
context = zmq_ctx_new();
subscriber = zmq_socket(context, ZMQ_SUB);
zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, "", 0);
zmq_connect(subscriber, "tcp://127.0.0.1:8006");
for (auto dbci : g_dbc) {
if (dbci->name == dbc_name) {
dbc = dbci;
break;
}
}
assert(dbc);
for (auto &op : options) {
MessageState state = {
.address = op.address,
// .check_frequency = op.check_frequency,
};
// msg is not valid if a message isn't received for 10 consecutive steps
if (op.check_frequency > 0) {
state.check_threshold = (1000000000ULL / op.check_frequency) * 10;
}
const Msg* msg = NULL;
for (int i=0; i<dbc->num_msgs; i++) {
if (dbc->msgs[i].address == op.address) {
msg = &dbc->msgs[i];
break;
}
}
if (!msg) {
fprintf(stderr, "CANParser: could not find message 0x%X in dnc %s\n", op.address, dbc_name.c_str());
assert(false);
}
// track checksums and for this message
for (int i=0; i<msg->num_sigs; i++) {
const Signal *sig = &msg->sigs[i];
if (sig->type == HONDA_CHECKSUM
|| sig->type == HONDA_COUNTER) {
state.parse_sigs.push_back(*sig);
state.vals.push_back(0);
}
}
// track requested signals for this message
for (auto &sigop : sigoptions) {
if (sigop.address != op.address) continue;
for (int i=0; i<msg->num_sigs; i++) {
const Signal *sig = &msg->sigs[i];
if (strcmp(sig->name, sigop.name) == 0
&& sig->type != HONDA_CHECKSUM
&& sig->type != HONDA_COUNTER) {
state.parse_sigs.push_back(*sig);
state.vals.push_back(sigop.default_value);
break;
}
}
}
message_states[state.address] = state;
}
}
void UpdateCans(uint64_t sec, const capnp::List<cereal::CanData>::Reader& cans) {
int msg_count = cans.size();
DEBUG("got %d messages\n", msg_count);
// parse the messages
for (int i = 0; i < msg_count; i++) {
auto cmsg = cans[i];
if (cmsg.getSrc() != bus) {
// DEBUG("skip %d: wrong bus\n", cmsg.getAddress());
continue;
}
auto state_it = message_states.find(cmsg.getAddress());
if (state_it == message_states.end()) {
// DEBUG("skip %d: not specified\n", cmsg.getAddress());
continue;
}
if (cmsg.getDat().size() > 8) continue; //shouldnt ever happen
uint8_t dat[8] = {0};
memcpy(dat, cmsg.getDat().begin(), cmsg.getDat().size());
uint64_t p = read_u64_be(dat);
DEBUG(" proc %X: %lx\n", cmsg.getAddress(), p);
state_it->second.parse(sec, p);
}
}
void UpdateValid(uint64_t sec) {
can_valid = true;
for (auto &kv : message_states) {
auto &state = kv.second;
if (state.check_threshold > 0 && (sec - state.seen) > state.check_threshold) {
if (state.seen > 0) {
INFO("%X TIMEOUT\n", state.address);
}
can_valid = false;
}
}
}
void update(uint64_t sec, bool wait) {
int err;
// recv from can
zmq_msg_t msg;
zmq_msg_init(&msg);
// multiple recv is fine
bool first = wait;
while (1) {
if (first) {
err = zmq_msg_recv(&msg, subscriber, 0);
first = false;
} else {
err = zmq_msg_recv(&msg, subscriber, ZMQ_DONTWAIT);
}
if (err < 0) break;
// format for board, make copy due to alignment issues, will be freed on out of scope
auto amsg = kj::heapArray<capnp::word>((zmq_msg_size(&msg) / sizeof(capnp::word)) + 1);
memcpy(amsg.begin(), zmq_msg_data(&msg), zmq_msg_size(&msg));
// extract the messages
capnp::FlatArrayMessageReader cmsg(amsg);
cereal::Event::Reader event = cmsg.getRoot<cereal::Event>();
auto cans = event.getCan();
UpdateCans(sec, cans);
}
UpdateValid(sec);
}
std::vector<SignalValue> query(uint64_t sec) {
std::vector<SignalValue> ret;
for (auto &kv : message_states) {
auto &state = kv.second;
if (sec != 0 && state.seen != sec) continue;
for (int i=0; i<state.parse_sigs.size(); i++) {
const Signal &sig = state.parse_sigs[i];
ret.push_back((SignalValue){
.address = state.address,
.name = sig.name,
.value = state.vals[i],
});
}
}
return ret;
}
bool can_valid = false;
private:
const int bus;
// zmq vars
void *context = NULL;
void *subscriber = NULL;
const DBC *dbc = NULL;
std::unordered_map<uint32_t, MessageState> message_states;
};
}
void dbc_register(const DBC* dbc) {
g_dbc.push_back(dbc);
}
extern "C" {
void* can_init(int bus, const char* dbc_name,
size_t num_message_options, const MessageParseOptions* message_options,
size_t num_signal_options, const SignalParseOptions* signal_options) {
CANParser* ret = new CANParser(bus, std::string(dbc_name),
(message_options ? std::vector<MessageParseOptions>(message_options, message_options+num_message_options)
: std::vector<MessageParseOptions>{}),
(signal_options ? std::vector<SignalParseOptions>(signal_options, signal_options+num_signal_options)
: std::vector<SignalParseOptions>{}));
return (void*)ret;
}
void can_update(void* can, uint64_t sec, bool wait) {
CANParser* cp = (CANParser*)can;
cp->update(sec, wait);
}
size_t can_query(void* can, uint64_t sec, bool *out_can_valid, size_t out_values_size, SignalValue* out_values) {
CANParser* cp = (CANParser*)can;
if (out_can_valid) {
*out_can_valid = cp->can_valid;
}
const std::vector<SignalValue> values = cp->query(sec);
if (out_values) {
std::copy(values.begin(), values.begin()+std::min(out_values_size, values.size()), out_values);
}
return values.size();
};
}
#ifdef TEST
int main(int argc, char** argv) {
CANParser cp(0, "honda_civic_touring_2016_can",
std::vector<MessageParseOptions>{
// address, check_frequency
{0x14a, 100},
{0x158, 100},
{0x17c, 100},
{0x191, 100},
{0x1a4, 50},
{0x326, 10},
{0x1b0, 50},
{0x1d0, 50},
{0x305, 10},
{0x324, 10},
{0x405, 3},
{0x18f, 0},
{0x130, 0},
{0x296, 0},
{0x30c, 0},
},
std::vector<SignalParseOptions>{
// sig_name, sig_address, default
{0x158, "XMISSION_SPEED", 0},
{0x1d0, "WHEEL_SPEED_FL", 0},
{0x1d0, "WHEEL_SPEED_FR", 0},
{0x1d0, "WHEEL_SPEED_RL", 0},
{0x14a, "STEER_ANGLE", 0},
{0x18f, "STEER_TORQUE_SENSOR", 0},
{0x191, "GEAR", 0},
{0x1b0, "WHEELS_MOVING", 1},
{0x405, "DOOR_OPEN_FL", 1},
{0x405, "DOOR_OPEN_FR", 1},
{0x405, "DOOR_OPEN_RL", 1},
{0x405, "DOOR_OPEN_RR", 1},
{0x324, "CRUISE_SPEED_PCM", 0},
{0x305, "SEATBELT_DRIVER_LAMP", 1},
{0x305, "SEATBELT_DRIVER_LATCHED", 0},
{0x17c, "BRAKE_PRESSED", 0},
{0x130, "CAR_GAS", 0},
{0x296, "CRUISE_BUTTONS", 0},
{0x1a4, "ESP_DISABLED", 1},
{0x30c, "HUD_LEAD", 0},
{0x1a4, "USER_BRAKE", 0},
{0x18f, "STEER_STATUS", 5},
{0x1d0, "WHEEL_SPEED_RR", 0},
{0x1b0, "BRAKE_ERROR_1", 1},
{0x1b0, "BRAKE_ERROR_2", 1},
{0x191, "GEAR_SHIFTER", 0},
{0x326, "MAIN_ON", 0},
{0x17c, "ACC_STATUS", 0},
{0x17c, "PEDAL_GAS", 0},
{0x296, "CRUISE_SETTING", 0},
{0x326, "LEFT_BLINKER", 0},
{0x326, "RIGHT_BLINKER", 0},
{0x324, "COUNTER", 0},
{0x17c, "ENGINE_RPM", 0},
});
const std::string log_fn = "dats.bin";
int log_fd = open(log_fn.c_str(), O_RDONLY, 0);
assert(log_fd >= 0);
off_t log_size = lseek(log_fd, 0, SEEK_END);
lseek(log_fd, 0, SEEK_SET);
void* log_data = mmap(NULL, log_size, PROT_READ, MAP_PRIVATE, log_fd, 0);
assert(log_data);
auto words = kj::arrayPtr((const capnp::word*)log_data, log_size/sizeof(capnp::word));
while (words.size() > 0) {
capnp::FlatArrayMessageReader reader(words);
auto evt = reader.getRoot<cereal::Event>();
auto cans = evt.getCan();
cp.UpdateCans(0, cans);
words = kj::arrayPtr(reader.getEnd(), words.end());
}
munmap(log_data, log_size);
close(log_fd);
return 0;
}
#endif

166
selfdrive/can/parser.py Normal file
View File

@@ -0,0 +1,166 @@
import os
import time
import subprocess
from collections import defaultdict
from cffi import FFI
can_dir = os.path.dirname(os.path.abspath(__file__))
libdbc_fn = os.path.join(can_dir, "libdbc.so")
subprocess.check_output(["make"], cwd=can_dir)
ffi = FFI()
ffi.cdef("""
typedef struct SignalParseOptions {
uint32_t address;
const char* name;
double default_value;
} SignalParseOptions;
typedef struct MessageParseOptions {
uint32_t address;
int check_frequency;
} MessageParseOptions;
typedef struct SignalValue {
uint32_t address;
const char* name;
double value;
} SignalValue;
void* can_init(int bus, const char* dbc_name,
size_t num_message_options, const MessageParseOptions* message_options,
size_t num_signal_options, const SignalParseOptions* signal_options);
void can_update(void* can, uint64_t sec, bool wait);
size_t can_query(void* can, uint64_t sec, bool *out_can_valid, size_t out_values_size, SignalValue* out_values);
""")
libdbc = ffi.dlopen(libdbc_fn)
class CANParser(object):
def __init__(self, dbc_name, signals, checks=[], bus=0):
self.can_valid = True
self.vl = defaultdict(dict)
sig_names = dict((name, ffi.new("char[]", name)) for name, _, _ in signals)
signal_options_c = ffi.new("SignalParseOptions[]", [
{
'address': sig_address,
'name': sig_names[sig_name],
'default_value': sig_default,
} for sig_name, sig_address, sig_default in signals])
message_options = dict((address, 0) for _, address, _ in signals)
message_options.update(dict(checks))
message_options_c = ffi.new("MessageParseOptions[]", [
{
'address': address,
'check_frequency': freq,
} for address, freq in message_options.iteritems()])
self.can = libdbc.can_init(bus, dbc_name, len(message_options_c), message_options_c,
len(signal_options_c), signal_options_c)
self.p_can_valid = ffi.new("bool*")
value_count = libdbc.can_query(self.can, 0, self.p_can_valid, 0, ffi.NULL)
self.can_values = ffi.new("SignalValue[%d]" % value_count)
self.update_vl(0)
# print "==="
def update_vl(self, sec):
can_values_len = libdbc.can_query(self.can, sec, self.p_can_valid, len(self.can_values), self.can_values)
assert can_values_len <= len(self.can_values)
self.can_valid = self.p_can_valid[0]
# print can_values_len
ret = set()
for i in xrange(can_values_len):
cv = self.can_values[i]
address = cv.address
# print hex(cv.address), ffi.string(cv.name)
self.vl[address][ffi.string(cv.name)] = cv.value
ret.add(address)
return ret
def update(self, sec, wait):
libdbc.can_update(self.can, sec, wait)
return self.update_vl(sec)
if __name__ == "__main__":
from common.realtime import sec_since_boot
radar_messages = range(0x430, 0x43A) + range(0x440, 0x446)
# signals = zip(['LONG_DIST'] * 16 + ['NEW_TRACK'] * 16 + ['LAT_DIST'] * 16 +
# ['REL_SPEED'] * 16, radar_messages * 4,
# [255] * 16 + [1] * 16 + [0] * 16 + [0] * 16)
# checks = zip(radar_messages, [20]*16)
# cp = CANParser("acura_ilx_2016_nidec", signals, checks, 1)
signals = [
("XMISSION_SPEED", 0x158, 0), #sig_name, sig_address, default
("WHEEL_SPEED_FL", 0x1d0, 0),
("WHEEL_SPEED_FR", 0x1d0, 0),
("WHEEL_SPEED_RL", 0x1d0, 0),
("STEER_ANGLE", 0x14a, 0),
("STEER_TORQUE_SENSOR", 0x18f, 0),
("GEAR", 0x191, 0),
("WHEELS_MOVING", 0x1b0, 1),
("DOOR_OPEN_FL", 0x405, 1),
("DOOR_OPEN_FR", 0x405, 1),
("DOOR_OPEN_RL", 0x405, 1),
("DOOR_OPEN_RR", 0x405, 1),
("CRUISE_SPEED_PCM", 0x324, 0),
("SEATBELT_DRIVER_LAMP", 0x305, 1),
("SEATBELT_DRIVER_LATCHED", 0x305, 0),
("BRAKE_PRESSED", 0x17c, 0),
("CAR_GAS", 0x130, 0),
("CRUISE_BUTTONS", 0x296, 0),
("ESP_DISABLED", 0x1a4, 1),
("HUD_LEAD", 0x30c, 0),
("USER_BRAKE", 0x1a4, 0),
("STEER_STATUS", 0x18f, 5),
("WHEEL_SPEED_RR", 0x1d0, 0),
("BRAKE_ERROR_1", 0x1b0, 1),
("BRAKE_ERROR_2", 0x1b0, 1),
("GEAR_SHIFTER", 0x191, 0),
("MAIN_ON", 0x326, 0),
("ACC_STATUS", 0x17c, 0),
("PEDAL_GAS", 0x17c, 0),
("CRUISE_SETTING", 0x296, 0),
("LEFT_BLINKER", 0x326, 0),
("RIGHT_BLINKER", 0x326, 0),
("COUNTER", 0x324, 0),
("ENGINE_RPM", 0x17C, 0)
]
checks = [
(0x14a, 100), # address, frequency
(0x158, 100),
(0x17c, 100),
(0x191, 100),
(0x1a4, 50),
(0x326, 10),
(0x1b0, 50),
(0x1d0, 50),
(0x305, 10),
(0x324, 10),
(0x405, 3),
]
cp = CANParser("honda_civic_touring_2016_can", signals, checks, 0)
print cp.vl
while True:
cp.update(int(sec_since_boot()*1e9), True)
print cp.vl
print cp.can_valid
time.sleep(0.01)

View File

@@ -0,0 +1,63 @@
#ifndef PARSER_COMMON_H
#define PARSER_COMMON_H
#include <cstddef>
#include <cstdint>
#define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0]))
struct SignalParseOptions {
uint32_t address;
const char* name;
double default_value;
};
struct MessageParseOptions {
uint32_t address;
int check_frequency;
};
struct SignalValue {
uint32_t address;
const char* name;
double value;
};
enum SignalType {
DEFAULT,
HONDA_CHECKSUM,
HONDA_COUNTER,
};
struct Signal {
const char* name;
int b1, b2, bo;
bool is_signed;
double factor, offset;
SignalType type;
};
struct Msg {
const char* name;
uint32_t address;
size_t num_sigs;
const Signal *sigs;
};
struct DBC {
const char* name;
size_t num_msgs;
const Msg *msgs;
};
void dbc_register(const DBC* dbc);
#define dbc_init(dbc) \
static void __attribute__((constructor)) do_dbc_init_ ## dbc(void) { \
dbc_register(&dbc); \
}
#endif

32
selfdrive/can/process_dbc.py Executable file
View File

@@ -0,0 +1,32 @@
#!/usr/bin/env python
import os
import sys
import jinja2
import opendbc
from common.dbc import dbc
if len(sys.argv) != 3:
print "usage: %s dbc_path struct_path" % (sys.argv[0],)
sys.exit(0)
dbc_fn = sys.argv[1]
out_fn = sys.argv[2]
template_fn = os.path.join(os.path.dirname(__file__), "dbc_template.cc")
can_dbc = dbc(dbc_fn)
with open(template_fn, "r") as template_f:
template = jinja2.Template(template_f.read(), trim_blocks=True, lstrip_blocks=True)
msgs = [(address, msg_name, sorted(msg_sigs, key=lambda s: s.name not in ("COUNTER", "CHECKSUM"))) # process counter and checksums first
for address, ((msg_name, _), msg_sigs) in sorted(can_dbc.msgs.iteritems()) if msg_sigs]
checksum_type = "honda" if can_dbc.name.startswith("honda") or can_dbc.name.startswith("acura") else None
parser_code = template.render(dbc=can_dbc, checksum_type=checksum_type, msgs=msgs, len=len)
with open(out_fn, "w") as out_f:
out_f.write(parser_code)

View File

@@ -0,0 +1,30 @@
from common.fingerprints import fingerprint
from .honda.interface import CarInterface as HondaInterface
try:
from .simulator.interface import CarInterface as SimInterface
except ImportError:
SimInterface = None
try:
from .simulator2.interface import CarInterface as Sim2Interface
except ImportError:
Sim2Interface = None
interfaces = {
"HONDA CIVIC 2016 TOURING": HondaInterface,
"ACURA ILX 2016 ACURAWATCH PLUS": HondaInterface,
"HONDA ACCORD 2016 TOURING": HondaInterface,
"HONDA CR-V 2016 TOURING": HondaInterface,
"simulator": SimInterface,
"simulator2": Sim2Interface
}
def get_car(logcan, sendcan=None):
candidate, fingerprints = fingerprint(logcan)
interface_cls = interfaces[candidate]
params = interface_cls.get_params(candidate, fingerprints)
return interface_cls(params, logcan, sendcan), params

View File

@@ -1,5 +1,5 @@
import os
import dbcs
import opendbc
from collections import defaultdict
from selfdrive.car.honda.hondacan import fix
@@ -19,12 +19,12 @@ class CANParser(object):
# monitored.
# - frequency is the frequency at which health should be monitored.
self.msgs_ck = [check[0] for check in checks]
self.frqs = [check[1] for check in checks]
self.msgs_ck = set([check[0] for check in checks])
self.frqs = dict(checks)
self.can_valid = False # start with False CAN assumption
# list of received msg we want to monitor counter and checksum for
# read dbc file
self.can_dbc = dbc(os.path.join(dbcs.DBC_PATH, dbc_f))
self.can_dbc = dbc(os.path.join(opendbc.DBC_PATH, dbc_f))
# initialize variables to initial values
self.vl = {} # signal values
self.ts = {} # time stamp recorded in log
@@ -57,6 +57,8 @@ class CANParser(object):
msgs_upd = []
cn_vl_max = 5 # no more than 5 wrong counter checks
self.sec_since_boot_cached = sec_since_boot()
# we are subscribing to PID_XXX, else data from USB
for msg, ts, cdat, _ in can_recv:
idxs = self._message_indices[msg]
@@ -93,7 +95,7 @@ class CANParser(object):
# update msg time stamps and counter value
self.ts[msg] = ts
self.ct[msg] = sec_since_boot()
self.ct[msg] = self.sec_since_boot_cached
self.cn[msg] = cn
self.cn_vl[msg] = min(max(self.cn_vl[msg], 0), cn_vl_max)
@@ -121,5 +123,5 @@ class CANParser(object):
### input:
## simple stuff for now: msg is not valid if a message isn't received for 10 consecutive steps
for msg in set(self._msgs):
if msg in self.msgs_ck and sec_since_boot() - self.ct[msg] > 10./self.frqs[self.msgs_ck.index(msg)]:
if msg in self.msgs_ck and self.sec_since_boot_cached - self.ct[msg] > 10./self.frqs[msg]:
self.ok[msg] = False

View File

@@ -1,11 +1,14 @@
from collections import namedtuple
import common.numpy_fast as np
from common.numpy_fast import clip, interp
from common.realtime import sec_since_boot
from selfdrive.config import CruiseButtons
from selfdrive.boardd.boardd import can_list_to_can_capnp
from selfdrive.controls.lib.drive_helpers import rate_limit
from common.numpy_fast import clip, interp
from . import hondacan
def actuator_hystereses(final_brake, braking, brake_steady, v_ego, civic):
# hyst params... TODO: move these to VehicleParams
@@ -55,7 +58,7 @@ def process_hud_alert(hud_alert):
fcw_display = 0
steer_required = 0
acc_alert = 0
if hud_alert == AH.NONE: # no alert
if hud_alert == AH.NONE: # no alert
pass
elif hud_alert == AH.FCW: # FCW
fcw_display = hud_alert[1]
@@ -66,7 +69,6 @@ def process_hud_alert(hud_alert):
return fcw_display, steer_required, acc_alert
import selfdrive.car.honda.hondacan as hondacan
HUDData = namedtuple("HUDData",
["pcm_accel", "v_cruise", "X2", "car", "X4", "X5",
@@ -87,6 +89,10 @@ class CarController(object):
snd_beep, snd_chime):
""" Controls thread """
# TODO: Make the accord work.
if CS.accord:
return
# *** apply brake hysteresis ***
final_brake, self.braking, self.brake_steady = actuator_hystereses(final_brake, self.braking, self.brake_steady, CS.v_ego, CS.civic)
@@ -122,7 +128,7 @@ class CarController(object):
#print chime, alert_id, hud_alert
fcw_display, steer_required, acc_alert = process_hud_alert(hud_alert)
hud = HUDData(int(pcm_accel), int(hud_v_cruise), 0x01, hud_car,
hud = HUDData(int(pcm_accel), int(round(hud_v_cruise)), 0x01, hud_car,
0xc1, 0x41, hud_lanes + steer_required,
int(snd_beep), 0x48, (snd_chime << 5) + fcw_display, acc_alert)
@@ -136,7 +142,12 @@ class CarController(object):
tt = sec_since_boot()
GAS_MAX = 1004
BRAKE_MAX = 1024/4
STEER_MAX = 0xF00
if CS.civic:
STEER_MAX = 0x1000
elif CS.crv:
STEER_MAX = 0x300 # CR-V only uses 12-bits and requires a lower value
else:
STEER_MAX = 0xF00
GAS_OFFSET = 328
# steer torque is converted back to CAN reference (positive when steering right)
@@ -193,7 +204,7 @@ class CarController(object):
can_sends.append(hondacan.create_accord_steering_control(apply_steer, idx))
else:
idx = frame % 4
can_sends.append(hondacan.create_steering_control(apply_steer, idx))
can_sends.extend(hondacan.create_steering_control(apply_steer, CS.crv, idx))
# Send gas and brake commands.
if (frame % 2) == 0:
@@ -202,7 +213,7 @@ class CarController(object):
hondacan.create_brake_command(apply_brake, pcm_override,
pcm_cancel_cmd, hud.chime, idx))
if not CS.brake_only:
# send exactly zero if apply_gas is zero. Interceptor will send the max between read value and apply_gas.
# send exactly zero if apply_gas is zero. Interceptor will send the max between read value and apply_gas.
# This prevents unexpected pedal range rescaling
gas_amount = (apply_gas + GAS_OFFSET) * (apply_gas > 0)
can_sends.append(hondacan.create_gas_command(gas_amount, idx))
@@ -210,17 +221,16 @@ class CarController(object):
# Send dashboard UI commands.
if (frame % 10) == 0:
idx = (frame/10) % 4
can_sends.extend(hondacan.create_ui_commands(pcm_speed, hud, CS.civic, CS.accord, idx))
can_sends.extend(hondacan.create_ui_commands(pcm_speed, hud, CS.civic, CS.accord, CS.crv, idx))
# radar at 20Hz, but these msgs need to be sent at 50Hz on ilx (seems like an Acura bug)
if CS.civic or CS.accord:
if CS.civic or CS.accord or CS.crv:
radar_send_step = 5
else:
radar_send_step = 2
if (frame % radar_send_step) == 0:
idx = (frame/radar_send_step) % 4
can_sends.extend(hondacan.create_radar_commands(CS.v_ego, CS.civic, CS.accord, idx))
can_sends.extend(hondacan.create_radar_commands(CS.v_ego, CS.civic, CS.accord, CS.crv, idx))
sendcan.send(can_list_to_can_capnp(can_sends, msgtype='sendcan').to_bytes())

View File

@@ -1,15 +1,22 @@
import numpy as np
import os
import time
import selfdrive.messaging as messaging
import common.numpy_fast as np
from common.realtime import sec_since_boot
import selfdrive.messaging as messaging
from selfdrive.car.honda.can_parser import CANParser
from selfdrive.can.parser import CANParser as CANParserC
NEW_CAN = os.getenv("OLD_CAN") is None
def get_can_parser(CP):
# this function generates lists for signal, messages and initial values
if CP.carFingerprint == "HONDA CIVIC 2016 TOURING":
dbc_f = 'honda_civic_touring_2016_can.dbc'
signals = [
# sig_name, sig_address, default
("XMISSION_SPEED", 0x158, 0),
("WHEEL_SPEED_FL", 0x1d0, 0),
("WHEEL_SPEED_FR", 0x1d0, 0),
@@ -46,6 +53,7 @@ def get_can_parser(CP):
("ENGINE_RPM", 0x17C, 0)
]
checks = [
# address, frequency
(0x14a, 100),
(0x158, 100),
(0x17c, 100),
@@ -162,18 +170,73 @@ def get_can_parser(CP):
(0x324, 10),
(0x405, 3),
]
elif CP.carFingerprint == "HONDA CR-V 2016 TOURING":
dbc_f = 'honda_crv_touring_2016_can.dbc'
signals = [
("XMISSION_SPEED", 0x158, 0),
("WHEEL_SPEED_FL", 0x1d0, 0),
("WHEEL_SPEED_FR", 0x1d0, 0),
("WHEEL_SPEED_RL", 0x1d0, 0),
("STEER_ANGLE", 0x156, 0),
("STEER_TORQUE_SENSOR", 0x18f, 0),
("GEAR", 0x191, 0),
("WHEELS_MOVING", 0x1b0, 1),
("DOOR_OPEN_FL", 0x405, 1),
("DOOR_OPEN_FR", 0x405, 1),
("DOOR_OPEN_RL", 0x405, 1),
("DOOR_OPEN_RR", 0x405, 1),
("CRUISE_SPEED_PCM", 0x324, 0),
("SEATBELT_DRIVER_LAMP", 0x305, 1),
("SEATBELT_DRIVER_LATCHED", 0x305, 0),
("BRAKE_PRESSED", 0x17c, 0),
#("CAR_GAS", 0x130, 0),
("CRUISE_BUTTONS", 0x1a6, 0),
("ESP_DISABLED", 0x1a4, 1),
("HUD_LEAD", 0x30c, 0),
("USER_BRAKE", 0x1a4, 0),
("STEER_STATUS", 0x18f, 5),
("WHEEL_SPEED_RR", 0x1d0, 0),
("BRAKE_ERROR_1", 0x1b0, 1),
("BRAKE_ERROR_2", 0x1b0, 1),
("GEAR_SHIFTER", 0x191, 0),
("MAIN_ON", 0x1a6, 0),
("ACC_STATUS", 0x17c, 0),
("PEDAL_GAS", 0x17c, 0),
("CRUISE_SETTING", 0x1a6, 0),
("LEFT_BLINKER", 0x294, 0),
("RIGHT_BLINKER", 0x294, 0),
("COUNTER", 0x324, 0),
("ENGINE_RPM", 0x17C, 0)
]
checks = [
(0x156, 100),
(0x158, 100),
(0x17c, 100),
(0x191, 100),
(0x1a3, 50),
(0x1a4, 50),
(0x1a6, 50),
(0x1b0, 50),
(0x1d0, 50),
(0x305, 10),
(0x324, 10),
(0x405, 3),
]
# add gas interceptor reading if we are using it
if CP.enableGas:
signals.append(("INTERCEPTOR_GAS", 0x201, 0))
checks.append((0x201, 50))
return CANParser(dbc_f, signals, checks)
if NEW_CAN:
return CANParserC(os.path.splitext(dbc_f)[0], signals, checks, 0)
else:
return CANParser(dbc_f, signals, checks)
class CarState(object):
def __init__(self, CP, logcan):
self.civic = False
self.accord = False
self.crv = False
if CP.carFingerprint == "HONDA CIVIC 2016 TOURING":
self.civic = True
elif CP.carFingerprint == "ACURA ILX 2016 ACURAWATCH PLUS":
@@ -181,6 +244,8 @@ class CarState(object):
elif CP.carFingerprint == "HONDA ACCORD 2016 TOURING":
# fake civic
self.accord = True
elif CP.carFingerprint == "HONDA CR-V 2016 TOURING":
self.crv = True
else:
raise ValueError("unsupported car %s" % CP.carFingerprint)
@@ -202,9 +267,12 @@ class CarState(object):
# TODO: actually make this work
self.a_ego = 0.
def update(self, can_pub_main):
def update(self, can_pub_main=None):
cp = self.cp
cp.update_can(can_pub_main)
if NEW_CAN:
cp.update(int(sec_since_boot() * 1e9), False)
else:
cp.update_can(can_pub_main)
# copy can_valid
self.can_valid = cp.can_valid
@@ -278,6 +346,17 @@ class CarState(object):
self.blinker_on = cp.vl[0x294]['LEFT_BLINKER'] or cp.vl[0x294]['RIGHT_BLINKER']
self.left_blinker_on = cp.vl[0x294]['LEFT_BLINKER']
self.right_blinker_on = cp.vl[0x294]['RIGHT_BLINKER']
elif self.crv:
self.gear_shifter = cp.vl[0x191]['GEAR_SHIFTER']
self.angle_steers = cp.vl[0x156]['STEER_ANGLE']
self.gear = cp.vl[0x191]['GEAR']
self.cruise_setting = cp.vl[0x1A6]['CRUISE_SETTING']
self.cruise_buttons = cp.vl[0x1A6]['CRUISE_BUTTONS']
self.main_on = cp.vl[0x1A6]['MAIN_ON']
self.gear_shifter_valid = self.gear_shifter in [1,8] # TODO: 1/P allowed for debug
self.blinker_on = cp.vl[0x294]['LEFT_BLINKER'] or cp.vl[0x294]['RIGHT_BLINKER']
self.left_blinker_on = cp.vl[0x294]['LEFT_BLINKER']
self.right_blinker_on = cp.vl[0x294]['RIGHT_BLINKER']
else:
self.gear_shifter = cp.vl[0x1A3]['GEAR_SHIFTER']
self.angle_steers = cp.vl[0x156]['STEER_ANGLE']
@@ -293,6 +372,10 @@ class CarState(object):
# on the accord, this doesn't seem to include cruise control
self.car_gas = cp.vl[0x17C]['PEDAL_GAS']
self.steer_override = False
elif self.crv:
# like accord, crv doesn't include cruise control
self.car_gas = cp.vl[0x17C]['PEDAL_GAS']
self.steer_override = abs(cp.vl[0x18F]['STEER_TORQUE_SENSOR']) > 1200
else:
self.car_gas = cp.vl[0x130]['CAR_GAS']
self.steer_override = abs(cp.vl[0x18F]['STEER_TORQUE_SENSOR']) > 1200
@@ -304,4 +387,3 @@ class CarState(object):
self.pedal_gas = cp.vl[0x17C]['PEDAL_GAS']
self.hud_lead = cp.vl[0x30C]['HUD_LEAD']
self.counter_pcm = cp.vl[0x324]['COUNTER']

View File

@@ -50,7 +50,7 @@ def create_accord_steering_control(apply_steer, idx):
dat = [0, 0, 0x40, 0]
else:
dat = [0,0,0,0]
rp = clip(apply_steer/0xF, -0xFF, 0xFF)
rp = np.clip(apply_steer/0xF, -0xFF, 0xFF)
if rp < 0:
rp += 512
dat[0] |= (rp >> 5) & 0xf
@@ -68,12 +68,18 @@ def create_accord_steering_control(apply_steer, idx):
return [0,0,dat,8]
def create_steering_control(apply_steer, idx):
def create_steering_control(apply_steer, crv, idx):
"""Creates a CAN message for the Honda DBC STEERING_CONTROL."""
msg = struct.pack("!h", apply_steer) + ("\x80\x00" if apply_steer != 0 else "\x00\x00")
return make_can_msg(0xe4, msg, idx, 0)
commands = []
if crv:
msg_0x194 = struct.pack("!h", apply_steer << 4) + ("\x80" if apply_steer != 0 else "\x00")
commands.append(make_can_msg(0x194, msg_0x194, idx, 0))
else:
msg_0xe4 = struct.pack("!h", apply_steer) + ("\x80\x00" if apply_steer != 0 else "\x00\x00")
commands.append(make_can_msg(0xe4, msg_0xe4, idx, 0))
return commands
def create_ui_commands(pcm_speed, hud, civic, accord, idx):
def create_ui_commands(pcm_speed, hud, civic, accord, crv, idx):
"""Creates an iterable of CAN messages for the UIs."""
commands = []
pcm_speed_real = np.clip(int(round(pcm_speed / 0.002759506)), 0,
@@ -94,14 +100,15 @@ def create_ui_commands(pcm_speed, hud, civic, accord, idx):
commands.append(make_can_msg(0x39f, msg_0x39f, idx, 0))
return commands
def create_radar_commands(v_ego, civic, accord, idx):
def create_radar_commands(v_ego, civic, accord, crv, idx):
"""Creates an iterable of CAN messages for the radar system."""
commands = []
v_ego_kph = np.clip(int(round(v_ego * CV.MS_TO_KPH)), 0, 255)
speed = struct.pack('!B', v_ego_kph)
msg_0x300 = ("\xf9" + speed + "\x8a\xd0" +\
("\x20" if idx == 0 or idx == 3 else "\x00") +\
"\x00\x00")
("\x20" if idx == 0 or idx == 3 else "\x00") +\
"\x00\x00")
if civic:
msg_0x301 = "\x02\x38\x44\x32\x4f\x00\x00"
# add 8 on idx.
@@ -112,6 +119,9 @@ def create_radar_commands(v_ego, civic, accord, idx):
msg_0x301 = "\x0e\xd8\x52\x22\x56\x00\x00"
# add 0xc on idx? WTF is this?
commands.append(make_can_msg(0x300, msg_0x300, idx + 0xc, 1))
elif crv:
msg_0x301 = "\x00\x00\x50\x02\x51\x00\x00"
commands.append(make_can_msg(0x300, msg_0x300, idx, 1))
else:
msg_0x301 = "\x0f\x18\x51\x02\x5a\x00\x00"
commands.append(make_can_msg(0x300, msg_0x300, idx, 1))

View File

@@ -1,18 +1,20 @@
#!/usr/bin/env python
import os
import time
import numpy as np
import common.numpy_fast as np
from selfdrive.config import Conversions as CV
from selfdrive.car.honda.carstate import CarState
from selfdrive.car.honda.carcontroller import CarController, AH
from .carstate import CarState
from .carcontroller import CarController, AH
from selfdrive.boardd.boardd import can_capnp_to_can_list
from cereal import car
import zmq
from selfdrive.services import service_list
import selfdrive.messaging as messaging
NEW_CAN = os.getenv("OLD_CAN") is None
# Car button codes
class CruiseButtons:
RES_ACCEL = 4
@@ -35,7 +37,6 @@ class BP:
TRIPLE = 2
REPEATED = 1
class CarInterface(object):
def __init__(self, CP, logcan, sendcan=None):
self.logcan = logcan
@@ -55,19 +56,65 @@ class CarInterface(object):
if self.CS.accord:
self.accord_msg = []
@staticmethod
def get_params(candidate, fingerprint):
# pedal
brake_only = 0x201 not in fingerprint
ret = car.CarParams.new_message()
ret.carName = "honda"
ret.radarName = "nidec"
ret.carFingerprint = candidate
ret.enableSteer = True
ret.enableBrake = True
ret.enableGas = not brake_only
ret.enableCruise = brake_only
#ret.enableCruise = False
# TODO: those parameters should be platform dependent
ret.wheelBase = 2.67
ret.slipFactor = 0.0014
if candidate == "HONDA CIVIC 2016 TOURING":
ret.steerRatio = 13.0
ret.steerKp, ret.steerKi = 6.0, 1.4
elif candidate == "ACURA ILX 2016 ACURAWATCH PLUS":
ret.steerRatio = 15.3
if not brake_only:
# assuming if we have an interceptor we also have a torque mod
ret.steerKp, ret.steerKi = 3.0, 0.7
else:
ret.steerKp, ret.steerKi = 6.0, 1.4
elif candidate == "HONDA ACCORD 2016 TOURING":
ret.steerRatio = 15.3
ret.steerKp, ret.steerKi = 6.0, 1.4
elif candidate == "HONDA CR-V 2016 TOURING":
ret.steerRatio = 15.3
ret.steerKp, ret.steerKi = 3.0, 0.7
else:
raise ValueError("unsupported car %s" % candidate)
return ret
# returns a car.CarState
def update(self):
# ******************* do can recv *******************
can_pub_main = []
canMonoTimes = []
for a in messaging.drain_sock(self.logcan):
canMonoTimes.append(a.logMonoTime)
can_pub_main.extend(can_capnp_to_can_list(a.can, [0,2]))
if self.CS.accord:
self.accord_msg.extend(can_capnp_to_can_list(a.can, [9]))
self.accord_msg = self.accord_msg[-1:]
self.CS.update(can_pub_main)
if NEW_CAN:
self.CS.update(can_pub_main)
else:
for a in messaging.drain_sock(self.logcan):
canMonoTimes.append(a.logMonoTime)
can_pub_main.extend(can_capnp_to_can_list(a.can, [0,0x80]))
if self.CS.accord:
self.accord_msg.extend(can_capnp_to_can_list(a.can, [9]))
self.accord_msg = self.accord_msg[-1:]
self.CS.update(can_pub_main)
# create message
ret = car.CarState.new_message()
@@ -115,6 +162,7 @@ class CarInterface(object):
# cruise state
ret.cruiseState.enabled = self.CS.pcm_acc_status != 0
ret.cruiseState.speed = self.CS.v_cruise_pcm * CV.KPH_TO_MS
ret.cruiseState.available = bool(self.CS.main_on)
# TODO: button presses
buttonEvents = []
@@ -178,7 +226,7 @@ class CarInterface(object):
if self.CS.steer_error:
errors.append('steerUnavailable')
elif self.CS.steer_not_allowed:
errors.append('steerTemporarilyUnavailable')
errors.append('steerTempUnavailable')
if self.CS.brake_error:
errors.append('brakeUnavailable')
if not self.CS.gear_shifter_valid:
@@ -212,7 +260,7 @@ class CarInterface(object):
hud_v_cruise = 255
hud_alert = {
"none": AH.NONE,
"none": AH.NONE,
"fcw": AH.FCW,
"steerRequired": AH.STEER,
"brakePressed": AH.BRAKE_PRESSED,
@@ -246,4 +294,3 @@ class CarInterface(object):
self.frame += 1
return not (c.enabled and not self.CC.controls_allowed)

View File

@@ -38,7 +38,7 @@ extern "C" void framebuffer_set_power(FramebufferState *s, int mode) {
}
extern "C" FramebufferState* framebuffer_init(
const char* name, int32_t layer,
const char* name, int32_t layer, int alpha,
EGLDisplay *out_display, EGLSurface *out_surface,
int *out_w, int *out_h) {
status_t status;
@@ -86,6 +86,7 @@ extern "C" FramebufferState* framebuffer_init(
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, alpha ? 8 : 0,
EGL_DEPTH_SIZE, 0,
EGL_STENCIL_SIZE, 8,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR,

View File

@@ -10,7 +10,7 @@ extern "C" {
typedef struct FramebufferState FramebufferState;
FramebufferState* framebuffer_init(
const char* name, int32_t layer,
const char* name, int32_t layer, int alpha,
EGLDisplay *out_display, EGLSurface *out_surface,
int *out_w, int *out_h);

View File

@@ -47,6 +47,12 @@ int write_db_value(const char* params_path, const char* key, const char* value,
goto cleanup;
}
// fsync to force persist the changes.
result = fsync(tmp_fd);
if (result < 0) {
goto cleanup;
}
// Move temp into place.
result = rename(tmp_path, path);

View File

@@ -12,6 +12,7 @@
#include <json.h>
#include "common/timing.h"
#include "common/version.h"
#include "swaglog.h"
@@ -28,6 +29,10 @@ static LogState s = {
.lock = PTHREAD_MUTEX_INITIALIZER,
};
static void cloudlog_bind_locked(const char* k, const char* v) {
json_append_member(s.ctx_j, k, json_mkstring(v));
}
static void cloudlog_init() {
if (s.inited) return;
s.ctx_j = json_mkobject();
@@ -47,6 +52,15 @@ static void cloudlog_init() {
}
}
// openpilot bindings
char* dongle_id = getenv("DONGLE_ID");
if (dongle_id) {
cloudlog_bind_locked("dongle_id", dongle_id);
}
cloudlog_bind_locked("version", OPENPILOT_VERSION);
bool dirty = !getenv("CLEAN");
json_append_member(s.ctx_j, "dirty", json_mkbool(dirty));
s.inited = true;
}
@@ -100,6 +114,6 @@ void cloudlog_e(int levelnum, const char* filename, int lineno, const char* func
void cloudlog_bind(const char* k, const char* v) {
pthread_mutex_lock(&s.lock);
cloudlog_init();
json_append_member(s.ctx_j, k, json_mkstring(v));
cloudlog_bind_locked(k, v);
pthread_mutex_unlock(&s.lock);
}

View File

@@ -4,6 +4,10 @@
#include <stdint.h>
#include <time.h>
#ifdef __APPLE__
#define CLOCK_BOOTTIME CLOCK_REALTIME
#endif
static inline uint64_t nanos_since_boot() {
struct timespec t;
clock_gettime(CLOCK_BOOTTIME, &t);

View File

@@ -12,13 +12,16 @@ void* read_file(const char* path, size_t* out_len) {
long f_len = ftell(f);
rewind(f);
char* buf = malloc(f_len + 1);
char* buf = calloc(f_len + 1, 1);
assert(buf);
memset(buf, 0, f_len + 1);
size_t num_read = fread(buf, f_len, 1, f);
assert(num_read == 1);
fclose(f);
if (num_read != 1) {
return NULL;
}
if (out_len) {
*out_len = f_len + 1;
}

View File

@@ -19,7 +19,10 @@
#define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0]))
// Reads a file into a newly allocated buffer.
//
// Returns NULL on failure, otherwise the NULL-terminated file contents.
// The result must be freed by the caller.
void* read_file(const char* path, size_t* out_len);

View File

@@ -5,6 +5,7 @@
#include <unistd.h>
#include <string>
#include <memory>
#include <sstream>
#include <fstream>

View File

@@ -1 +1 @@
const char *openpilot_version = "0.3.0";
#define OPENPILOT_VERSION "0.3.4"

View File

@@ -1,21 +1,23 @@
#!/usr/bin/env python
import os
import zmq
import numpy as np
import selfdrive.messaging as messaging
from copy import copy
from cereal import car, log
from selfdrive.swaglog import cloudlog
from common.numpy_fast import clip
from common.fingerprints import fingerprint
from selfdrive.config import Conversions as CV
from selfdrive.services import service_list
from common.realtime import sec_since_boot, set_realtime_priority, Ratekeeper
from common.profiler import Profiler
from common.params import Params
from selfdrive.swaglog import cloudlog
from selfdrive.config import Conversions as CV
from selfdrive.services import service_list
from selfdrive.car import get_car
from selfdrive.controls.lib.planner import Planner
from selfdrive.controls.lib.drive_helpers import learn_angle_offset
from selfdrive.controls.lib.longcontrol import LongControl
@@ -28,315 +30,352 @@ V_CRUISE_MIN = 8
V_CRUISE_DELTA = 8
V_CRUISE_ENABLE_MIN = 40
def controlsd_thread(gctx, rate=100): #rate in Hz
# *** log ***
context = zmq.Context()
live100 = messaging.pub_sock(context, service_list['live100'].port)
carstate = messaging.pub_sock(context, service_list['carState'].port)
carcontrol = messaging.pub_sock(context, service_list['carControl'].port)
AWARENESS_TIME = 360. # 6 minutes limit without user touching steering wheels
AWARENESS_PRE_TIME = 20. # a first alert is issued 20s before start decelerating the car
AWARENESS_DECEL = -0.2 # car smoothly decel at .2m/s^2 when user is distracted
thermal = messaging.sub_sock(context, service_list['thermal'].port)
health = messaging.sub_sock(context, service_list['health'].port)
plan_sock = messaging.sub_sock(context, service_list['plan'].port)
# class Cal
class Calibration:
UNCALIBRATED = 0
CALIBRATED = 1
INVALID = 2
logcan = messaging.sub_sock(context, service_list['can'].port)
# to be used
class State():
DISABLED = 0
ENABLED = 1
SOFT_DISABLE = 2
# connects to can
CP = fingerprint(logcan)
class Controls(object):
def __init__(self, gctx, rate=100):
self.rate = rate
# import the car from the fingerprint
cloudlog.info("controlsd is importing %s", CP.carName)
exec('from selfdrive.car.'+CP.carName+'.interface import CarInterface')
# *** log ***
context = zmq.Context()
sendcan = messaging.pub_sock(context, service_list['sendcan'].port)
CI = CarInterface(CP, logcan, sendcan)
# pub
self.live100 = messaging.pub_sock(context, service_list['live100'].port)
self.carstate = messaging.pub_sock(context, service_list['carState'].port)
self.carcontrol = messaging.pub_sock(context, service_list['carControl'].port)
sendcan = messaging.pub_sock(context, service_list['sendcan'].port)
# sub
self.thermal = messaging.sub_sock(context, service_list['thermal'].port)
self.health = messaging.sub_sock(context, service_list['health'].port)
logcan = messaging.sub_sock(context, service_list['can'].port)
self.cal = messaging.sub_sock(context, service_list['liveCalibration'].port)
self.CC = car.CarControl.new_message()
self.CI, self.CP = get_car(logcan, sendcan)
self.PL = Planner(self.CP)
self.AM = AlertManager()
self.LoC = LongControl()
self.LaC = LatControl()
# write CarParams
params = Params()
params.put("CarParams", self.CP.to_bytes())
# fake plan
self.plan_ts = 0
self.plan = log.Plan.new_message()
self.plan.lateralValid = False
self.plan.longitudinalValid = False
# controls enabled state
self.enabled = False
self.last_enable_request = 0
# learned angle offset
self.angle_offset = 0
# rear view camera state
self.rear_view_toggle = False
self.rear_view_allowed = bool(params.get("IsRearViewMirror"))
self.v_cruise_kph = 255
# 0.0 - 1.0
self.awareness_status = 1.0
self.soft_disable_timer = None
self.overtemp = False
self.free_space = 1.0
self.cal_status = Calibration.UNCALIBRATED
self.cal_perc = 0
self.rk = Ratekeeper(self.rate, print_delay_threshold=2./1000)
def data_sample(self):
self.prof = Profiler()
self.cur_time = sec_since_boot()
# first read can and compute car states
self.CS = self.CI.update()
# write CarParams
Params().put("CarParams", CP.to_bytes())
AM = AlertManager()
LoC = LongControl()
LaC = LatControl()
# fake plan
plan = log.Plan.new_message()
plan.lateralValid = False
plan.longitudinalValid = False
last_plan_time = 0
# controls enabled state
enabled = False
last_enable_request = 0
# learned angle offset
angle_offset = 0
# rear view camera state
rear_view_toggle = False
v_cruise_kph = 255
# 0.0 - 1.0
awareness_status = 0.0
soft_disable_timer = None
# Is cpu temp too high to enable?
overtemp = False
free_space = 1.0
# start the loop
set_realtime_priority(2)
rk = Ratekeeper(rate, print_delay_threshold=2./1000)
while 1:
prof = Profiler()
cur_time = sec_since_boot()
# read CAN
CS = CI.update()
# broadcast carState
cs_send = messaging.new_message()
cs_send.init('carState')
cs_send.carState = CS # copy?
carstate.send(cs_send.to_bytes())
prof.checkpoint("CarInterface")
# did it request to enable?
enable_request, enable_condition = False, False
if enabled:
# gives the user 6 minutes
awareness_status -= 1.0/(100*60*6)
if awareness_status <= 0.:
AM.add("driverDistracted", enabled)
# reset awareness status on steering
if CS.steeringPressed:
awareness_status = 1.0
# handle button presses
for b in CS.buttonEvents:
print b
# reset awareness on any user action
awareness_status = 1.0
# button presses for rear view
if b.type == "leftBlinker" or b.type == "rightBlinker":
if b.pressed:
rear_view_toggle = True
else:
rear_view_toggle = False
if b.type == "altButton1" and b.pressed:
rear_view_toggle = not rear_view_toggle
if not CP.enableCruise and enabled and not b.pressed:
if b.type == "accelCruise":
v_cruise_kph = v_cruise_kph - (v_cruise_kph % V_CRUISE_DELTA) + V_CRUISE_DELTA
elif b.type == "decelCruise":
v_cruise_kph = v_cruise_kph - (v_cruise_kph % V_CRUISE_DELTA) - V_CRUISE_DELTA
v_cruise_kph = clip(v_cruise_kph, V_CRUISE_MIN, V_CRUISE_MAX)
if not enabled and b.type in ["accelCruise", "decelCruise"] and not b.pressed:
enable_request = True
# do disable on button down
if b.type == "cancel" and b.pressed:
AM.add("disable", enabled)
prof.checkpoint("Buttons")
# *** health checking logic ***
hh = messaging.recv_sock(health)
if hh is not None:
# if the board isn't allowing controls but somehow we are enabled!
if not hh.health.controlsAllowed and enabled:
AM.add("controlsMismatch", enabled)
self.prof.checkpoint("CarInterface")
# *** thermal checking logic ***
# thermal data, checked every second
td = messaging.recv_sock(thermal)
td = messaging.recv_sock(self.thermal)
if td is not None:
# Check temperature.
overtemp = any(
self.overtemp = any(
t > 950
for t in (td.thermal.cpu0, td.thermal.cpu1, td.thermal.cpu2,
td.thermal.cpu3, td.thermal.mem, td.thermal.gpu))
# under 15% of space free
free_space = td.thermal.freeSpace
self.free_space = td.thermal.freeSpace
prof.checkpoint("Health")
# read calibration status
cal = messaging.recv_sock(self.cal)
if cal is not None:
self.cal_status = cal.liveCalibration.calStatus
self.cal_perc = cal.liveCalibration.calPerc
def state_transition(self):
pass # for now
def state_control(self):
# did it request to enable?
enable_request, enable_condition = False, False
# reset awareness status on steering
if self.CS.steeringPressed or not self.enabled:
self.awareness_status = 1.0
elif self.enabled:
# gives the user 6 minutes
self.awareness_status -= 1.0/(self.rate * AWARENESS_TIME)
if self.awareness_status <= 0.:
self.AM.add("driverDistracted", self.enabled)
elif self.awareness_status <= AWARENESS_PRE_TIME / AWARENESS_TIME and \
self.awareness_status >= (AWARENESS_PRE_TIME - 0.1) / AWARENESS_TIME:
self.AM.add("preDriverDistracted", self.enabled)
# handle button presses
for b in self.CS.buttonEvents:
print b
# button presses for rear view
if b.type == "leftBlinker" or b.type == "rightBlinker":
if b.pressed and self.rear_view_allowed:
self.rear_view_toggle = True
else:
self.rear_view_toggle = False
if b.type == "altButton1" and b.pressed:
self.rear_view_toggle = not self.rear_view_toggle
if not self.CP.enableCruise and self.enabled and not b.pressed:
if b.type == "accelCruise":
self.v_cruise_kph -= (self.v_cruise_kph % V_CRUISE_DELTA) - V_CRUISE_DELTA
elif b.type == "decelCruise":
self.v_cruise_kph -= (self.v_cruise_kph % V_CRUISE_DELTA) + V_CRUISE_DELTA
self.v_cruise_kph = clip(self.v_cruise_kph, V_CRUISE_MIN, V_CRUISE_MAX)
if not self.enabled and b.type in ["accelCruise", "decelCruise"] and not b.pressed:
enable_request = True
# do disable on button down
if b.type == "cancel" and b.pressed:
self.AM.add("disable", self.enabled)
self.prof.checkpoint("Buttons")
# *** health checking logic ***
hh = messaging.recv_sock(self.health)
if hh is not None:
# if the board isn't allowing controls but somehow we are enabled!
# TODO: this should be in state transition with a function follower logic
if not hh.health.controlsAllowed and self.enabled:
self.AM.add("controlsMismatch", self.enabled)
# disable if the pedals are pressed while engaged, this is a user disable
if enabled:
if CS.gasPressed or CS.brakePressed:
AM.add("disable", enabled)
if self.enabled:
if self.CS.gasPressed or self.CS.brakePressed or not self.CS.cruiseState.available:
self.AM.add("disable", self.enabled)
# it can happen that car cruise disables while comma system is enabled: need to
# keep braking if needed or if the speed is very low
# TODO: for the Acura, cancellation below 25mph is normal. Issue a non loud alert
if self.CP.enableCruise and not self.CS.cruiseState.enabled and \
(self.CC.brake <= 0. or self.CS.vEgo < 0.3):
self.AM.add("cruiseDisabled", self.enabled)
if enable_request:
# check for pressed pedals
if CS.gasPressed or CS.brakePressed:
AM.add("pedalPressed", enabled)
if self.CS.gasPressed or self.CS.brakePressed:
self.AM.add("pedalPressed", self.enabled)
enable_request = False
else:
print "enabled pressed at", cur_time
last_enable_request = cur_time
print "enabled pressed at", self.cur_time
self.last_enable_request = self.cur_time
# don't engage with less than 15% free
if free_space < 0.15:
AM.add("outOfSpace", enabled)
if self.free_space < 0.15:
self.AM.add("outOfSpace", self.enabled)
enable_request = False
if CP.enableCruise:
enable_condition = ((cur_time - last_enable_request) < 0.2) and CS.cruiseState.enabled
if self.CP.enableCruise:
enable_condition = ((self.cur_time - self.last_enable_request) < 0.2) and self.CS.cruiseState.enabled
else:
enable_condition = enable_request
if CP.enableCruise and CS.cruiseState.enabled:
v_cruise_kph = CS.cruiseState.speed * CV.MS_TO_KPH
if self.CP.enableCruise and self.CS.cruiseState.enabled:
self.v_cruise_kph = self.CS.cruiseState.speed * CV.MS_TO_KPH
prof.checkpoint("AdaptiveCruise")
self.prof.checkpoint("AdaptiveCruise")
# *** what's the plan ***
new_plan = messaging.recv_sock(plan_sock)
if new_plan is not None:
plan = new_plan.plan
plan = plan.as_builder() # plan can change in controls
last_plan_time = cur_time
plan_packet = self.PL.update(self.CS, self.LoC)
self.plan = plan_packet.plan
self.plan_ts = plan_packet.logMonoTime
# check plan for timeout
if cur_time - last_plan_time > 0.5:
plan.lateralValid = False
plan.longitudinalValid = False
# if user is not responsive to awareness alerts, then start a smooth deceleration
if self.awareness_status < -0.:
self.plan.aTargetMax = min(self.plan.aTargetMax, AWARENESS_DECEL)
self.plan.aTargetMin = min(self.plan.aTargetMin, self.plan.aTargetMax)
# gives 18 seconds before decel begins (w 6 minute timeout)
if awareness_status < -0.05:
plan.aTargetMax = min(plan.aTargetMax, -0.2)
plan.aTargetMin = min(plan.aTargetMin, plan.aTargetMax)
if enable_request or enable_condition or enabled:
if enable_request or enable_condition or self.enabled:
# add all alerts from car
for alert in CS.errors:
AM.add(alert, enabled)
for alert in self.CS.errors:
self.AM.add(alert, self.enabled)
if not plan.longitudinalValid:
AM.add("radarCommIssue", enabled)
if not self.plan.longitudinalValid:
self.AM.add("radarCommIssue", self.enabled)
if not plan.lateralValid:
if self.cal_status != Calibration.CALIBRATED:
if self.cal_status == Calibration.UNCALIBRATED:
self.AM.add("calibrationInProgress", self.enabled, str(self.cal_perc) + '%')
else:
self.AM.add("calibrationInvalid", self.enabled)
if not self.plan.lateralValid:
# If the model is not broadcasting, assume that it is because
# the user has uploaded insufficient data for calibration.
# Other cases that would trigger this are rare and unactionable by the user.
AM.add("dataNeeded", enabled)
self.AM.add("dataNeeded", self.enabled)
if overtemp:
AM.add("overheat", enabled)
if self.overtemp:
self.AM.add("overheat", self.enabled)
# *** angle offset learning ***
if rk.frame % 5 == 2 and plan.lateralValid:
# *** run this at 20hz again ***
angle_offset = learn_angle_offset(enabled, CS.vEgo, angle_offset, np.asarray(plan.dPoly), LaC.y_des, CS.steeringPressed)
# *** angle offset learning ***
if self.rk.frame % 5 == 2 and self.plan.lateralValid:
# *** run this at 20hz again ***
self.angle_offset = learn_angle_offset(self.enabled, self.CS.vEgo, self.angle_offset,
self.plan.dPoly, self.LaC.y_des, self.CS.steeringPressed)
# *** gas/brake PID loop ***
final_gas, final_brake = LoC.update(enabled, CS.vEgo, v_cruise_kph,
plan.vTarget,
[plan.aTargetMin, plan.aTargetMax],
plan.jerkFactor, CP)
# *** gas/brake PID loop ***
final_gas, final_brake = self.LoC.update(self.enabled, self.CS.vEgo, self.v_cruise_kph,
self.plan.vTarget,
[self.plan.aTargetMin, self.plan.aTargetMax],
self.plan.jerkFactor, self.CP)
# *** steering PID loop ***
final_steer, sat_flag = LaC.update(enabled, CS.vEgo, CS.steeringAngle, CS.steeringPressed, plan.dPoly, angle_offset, CP)
# *** steering PID loop ***
final_steer, sat_flag = self.LaC.update(self.enabled, self.CS.vEgo, self.CS.steeringAngle,
self.CS.steeringPressed, self.plan.dPoly, self.angle_offset, self.CP)
self.prof.checkpoint("PID")
# ***** handle alerts ****
# send FCW alert if triggered by planner
if self.plan.fcw:
self.AM.add("fcw", self.enabled)
prof.checkpoint("PID")
# ***** handle alerts ****
# send a "steering required alert" if saturation count has reached the limit
if sat_flag:
AM.add("steerSaturated", enabled)
self.AM.add("steerSaturated", self.enabled)
if enabled and AM.alertShouldDisable():
if self.enabled and self.AM.alertShouldDisable():
print "DISABLING IMMEDIATELY ON ALERT"
enabled = False
self.enabled = False
if enabled and AM.alertShouldSoftDisable():
if soft_disable_timer is None:
soft_disable_timer = 3 * rate
elif soft_disable_timer == 0:
if self.enabled and self.AM.alertShouldSoftDisable():
if self.soft_disable_timer is None:
self.soft_disable_timer = 3 * self.rate
elif self.soft_disable_timer == 0:
print "SOFT DISABLING ON ALERT"
enabled = False
self.enabled = False
else:
soft_disable_timer -= 1
self.soft_disable_timer -= 1
else:
soft_disable_timer = None
self.soft_disable_timer = None
if enable_condition and not enabled and not AM.alertPresent():
if enable_condition and not self.enabled and not self.AM.alertPresent():
print "*** enabling controls"
# beep for enabling
AM.add("enable", enabled)
self.AM.add("enable", self.enabled)
# enable both lateral and longitudinal controls
enabled = True
self.enabled = True
# on activation, let's always set v_cruise from where we are, even if PCM ACC is active
v_cruise_kph = int(round(max(CS.vEgo * CV.MS_TO_KPH, V_CRUISE_ENABLE_MIN)))
self.v_cruise_kph = int(round(max(self.CS.vEgo * CV.MS_TO_KPH, V_CRUISE_ENABLE_MIN)))
# 6 minutes driver you're on
awareness_status = 1.0
self.awareness_status = 1.0
# reset the PID loops
LaC.reset()
self.LaC.reset()
# start long control at actual speed
LoC.reset(v_pid = CS.vEgo)
self.LoC.reset(v_pid = self.CS.vEgo)
# *** push the alerts to current ***
alert_text_1, alert_text_2, visual_alert, audible_alert = AM.process_alerts(cur_time)
# TODO: remove output, store them inside AM class instead
self.alert_text_1, self.alert_text_2, self.visual_alert, self.audible_alert = self.AM.process_alerts(self.cur_time)
# ***** control the car *****
CC = car.CarControl.new_message()
self.CC.enabled = self.enabled
CC.enabled = enabled
self.CC.gas = float(final_gas)
self.CC.brake = float(final_brake)
self.CC.steeringTorque = float(final_steer)
CC.gas = float(final_gas)
CC.brake = float(final_brake)
CC.steeringTorque = float(final_steer)
CC.cruiseControl.override = True
CC.cruiseControl.cancel = bool((not CP.enableCruise) or (not enabled and CS.cruiseState.enabled)) # always cancel if we have an interceptor
self.CC.cruiseControl.override = True
# always cancel if we have an interceptor
self.CC.cruiseControl.cancel = bool(not self.CP.enableCruise or
(not self.enabled and self.CS.cruiseState.enabled))
# brake discount removes a sharp nonlinearity
brake_discount = (1.0 - clip(final_brake*3., 0.0, 1.0))
CC.cruiseControl.speedOverride = float(max(0.0, ((LoC.v_pid - .5) * brake_discount)) if CP.enableCruise else 0.0)
self.CC.cruiseControl.speedOverride = float(max(0.0, ((self.LoC.v_pid - .5) * brake_discount)) if self.CP.enableCruise else 0.0)
#CC.cruiseControl.accelOverride = float(AC.a_pcm)
# TODO: fix this
CC.cruiseControl.accelOverride = float(1.0)
self.CC.cruiseControl.accelOverride = float(1.0)
CC.hudControl.setSpeed = float(v_cruise_kph * CV.KPH_TO_MS)
CC.hudControl.speedVisible = enabled
CC.hudControl.lanesVisible = enabled
#CC.hudControl.leadVisible = bool(AC.has_lead)
# TODO: fix this
CC.hudControl.leadVisible = False
CC.hudControl.visualAlert = visual_alert
CC.hudControl.audibleAlert = audible_alert
self.CC.hudControl.setSpeed = float(self.v_cruise_kph * CV.KPH_TO_MS)
self.CC.hudControl.speedVisible = self.enabled
self.CC.hudControl.lanesVisible = self.enabled
self.CC.hudControl.leadVisible = self.plan.hasLead
self.CC.hudControl.visualAlert = self.visual_alert
self.CC.hudControl.audibleAlert = self.audible_alert
# TODO: remove it from here and put it in state_transition
# this alert will apply next controls cycle
if not CI.apply(CC):
AM.add("controlsFailed", enabled)
if not self.CI.apply(self.CC):
self.AM.add("controlsFailed", self.enabled)
# broadcast carControl
def data_send(self):
# broadcast carControl first
cc_send = messaging.new_message()
cc_send.init('carControl')
cc_send.carControl = CC # copy?
carcontrol.send(cc_send.to_bytes())
cc_send.carControl = copy(self.CC)
self.carcontrol.send(cc_send.to_bytes())
prof.checkpoint("CarControl")
self.prof.checkpoint("CarControl")
# broadcast carState
cs_send = messaging.new_message()
cs_send.init('carState')
cs_send.carState = copy(self.CS)
self.carstate.send(cs_send.to_bytes())
# ***** publish state to logger *****
# publish controls state at 100Hz
@@ -344,55 +383,72 @@ def controlsd_thread(gctx, rate=100): #rate in Hz
dat.init('live100')
# show rear view camera on phone if in reverse gear or when button is pressed
dat.live100.rearViewCam = ('reverseGear' in CS.errors) or rear_view_toggle
dat.live100.alertText1 = alert_text_1
dat.live100.alertText2 = alert_text_2
dat.live100.awarenessStatus = max(awareness_status, 0.0) if enabled else 0.0
dat.live100.rearViewCam = ('reverseGear' in self.CS.errors and self.rear_view_allowed) or self.rear_view_toggle
dat.live100.alertText1 = self.alert_text_1
dat.live100.alertText2 = self.alert_text_2
dat.live100.awarenessStatus = max(self.awareness_status, 0.0) if self.enabled else 0.0
# what packets were used to process
dat.live100.canMonoTimes = list(CS.canMonoTimes)
#dat.live100.mdMonoTime = PP.logMonoTime
#dat.live100.l20MonoTime = AC.logMonoTime
dat.live100.canMonoTimes = list(self.CS.canMonoTimes)
dat.live100.planMonoTime = self.plan_ts
# if controls is enabled
dat.live100.enabled = enabled
dat.live100.enabled = self.enabled
# car state
dat.live100.vEgo = CS.vEgo
dat.live100.angleSteers = CS.steeringAngle
dat.live100.steerOverride = CS.steeringPressed
dat.live100.vEgo = self.CS.vEgo
dat.live100.angleSteers = self.CS.steeringAngle
dat.live100.steerOverride = self.CS.steeringPressed
# longitudinal control state
dat.live100.vPid = float(LoC.v_pid)
dat.live100.vCruise = float(v_cruise_kph)
dat.live100.upAccelCmd = float(LoC.Up_accel_cmd)
dat.live100.uiAccelCmd = float(LoC.Ui_accel_cmd)
dat.live100.vPid = float(self.LoC.v_pid)
dat.live100.vCruise = float(self.v_cruise_kph)
dat.live100.upAccelCmd = float(self.LoC.Up_accel_cmd)
dat.live100.uiAccelCmd = float(self.LoC.Ui_accel_cmd)
# lateral control state
dat.live100.yActual = float(LaC.y_actual)
dat.live100.yDes = float(LaC.y_des)
dat.live100.upSteer = float(LaC.Up_steer)
dat.live100.uiSteer = float(LaC.Ui_steer)
dat.live100.yActual = float(self.LaC.y_actual)
dat.live100.yDes = float(self.LaC.y_des)
dat.live100.upSteer = float(self.LaC.Up_steer)
dat.live100.uiSteer = float(self.LaC.Ui_steer)
# processed radar state, should add a_pcm?
dat.live100.vTargetLead = float(plan.vTarget)
dat.live100.aTargetMin = float(plan.aTargetMin)
dat.live100.aTargetMax = float(plan.aTargetMax)
dat.live100.jerkFactor = float(plan.jerkFactor)
dat.live100.vTargetLead = float(self.plan.vTarget)
dat.live100.aTargetMin = float(self.plan.aTargetMin)
dat.live100.aTargetMax = float(self.plan.aTargetMax)
dat.live100.jerkFactor = float(self.plan.jerkFactor)
# log learned angle offset
dat.live100.angleOffset = float(self.angle_offset)
# lag
dat.live100.cumLagMs = -rk.remaining*1000.
dat.live100.cumLagMs = -self.rk.remaining*1000.
live100.send(dat.to_bytes())
self.live100.send(dat.to_bytes())
prof.checkpoint("Live100")
self.prof.checkpoint("Live100")
def wait(self):
# *** run loop at fixed rate ***
if rk.keep_time():
prof.display()
if self.rk.keep_time():
self.prof.display()
def controlsd_thread(gctx, rate=100):
# start the loop
set_realtime_priority(2)
CTRLS = Controls(gctx, rate)
while 1:
CTRLS.data_sample()
CTRLS.state_transition()
CTRLS.state_control()
CTRLS.data_send()
CTRLS.wait()
def main(gctx=None):
controlsd_thread(gctx, 100)
if __name__ == "__main__":
main()

View File

@@ -214,28 +214,6 @@ def calc_jerk_factor(d_lead, v_rel):
return jerk_factor
def calc_ttc(d_rel, v_rel, a_rel, v_lead):
# this function returns the time to collision (ttc), assuming that a_rel will stay constant
# TODO: Review these assumptions.
# change sign to rel quantities as it's going to be easier for calculations
v_rel = -v_rel
a_rel = -a_rel
# assuming that closing gap a_rel comes from lead vehicle decel, then limit a_rel so that v_lead will get to zero in no sooner than t_decel
# this helps overweighting a_rel when v_lead is close to zero.
t_decel = 2.
a_rel = min(a_rel, v_lead/t_decel)
delta = v_rel**2 + 2 * d_rel * a_rel
# assign an arbitrary high ttc value if there is no solution to ttc
if delta < 0.1:
ttc = 5.
elif math.sqrt(delta) + v_rel < 0.1:
ttc = 5.
else:
ttc = 2 * d_rel / (math.sqrt(delta) + v_rel)
return ttc
MAX_SPEED_POSSIBLE = 55.
@@ -299,18 +277,14 @@ def compute_speed_with_leads(v_ego, angle_steers, v_pid, l1, l2, CP):
class AdaptiveCruise(object):
def __init__(self, live20):
self.live20 = live20
def __init__(self):
self.last_cal = 0.
self.l1, self.l2 = None, None
self.logMonoTime = 0
self.dead = True
def update(self, cur_time, v_ego, angle_steers, v_pid, CP):
l20 = messaging.recv_sock(self.live20)
def update(self, cur_time, v_ego, angle_steers, v_pid, CP, l20):
if l20 is not None:
self.l1 = l20.live20.leadOne
self.l2 = l20.live20.leadTwo
self.logMonoTime = l20.logMonoTime
# TODO: no longer has anything to do with calibration
self.last_cal = cur_time

View File

@@ -1,13 +1,14 @@
from cereal import car
from selfdrive.swaglog import cloudlog
import copy
class ET:
ENABLE = 0
NO_ENTRY = 1
WARNING = 2
SOFT_DISABLE = 3
IMMEDIATE_DISABLE = 4
USER_DISABLE = 5
USER_DISABLE = 3
SOFT_DISABLE = 4
IMMEDIATE_DISABLE = 5
class alert(object):
def __init__(self, alert_text_1, alert_text_2, alert_type, visual_alert, audible_alert, duration_sound, duration_hud_alert, duration_text):
@@ -34,32 +35,37 @@ class alert(object):
class AlertManager(object):
alerts = {
"enable": alert("", "", ET.ENABLE, None, "beepSingle", .2, 0., 0.),
"disable": alert("", "", ET.USER_DISABLE, None, "beepSingle", .2, 0., 0.),
"pedalPressed": alert("Comma Unavailable", "Pedal Pressed", ET.NO_ENTRY, "brakePressed", "chimeDouble", .4, 2., 3.),
"driverDistracted": alert("Take Control to Regain Speed", "User Distracted", ET.WARNING, "steerRequired", "chimeRepeated", 1., 1., 1.),
"steerSaturated": alert("Take Control", "Steer Control Saturated", ET.WARNING, "steerRequired", "chimeSingle", 1., 2., 3.),
"overheat": alert("Take Control Immediately", "System Overheated", ET.SOFT_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"controlsMismatch": alert("Take Control Immediately", "Controls Mismatch", ET.IMMEDIATE_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"radarCommIssue": alert("Take Control Immediately", "Radar Comm Issue", ET.IMMEDIATE_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"modelCommIssue": alert("Take Control Immediately", "Model Comm Issue", ET.IMMEDIATE_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"controlsFailed": alert("Take Control Immediately", "Controls Failed", ET.IMMEDIATE_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"enable": alert("", "", ET.ENABLE, None, "beepSingle", .2, 0., 0.),
"disable": alert("", "", ET.USER_DISABLE, None, "beepSingle", .2, 0., 0.),
"pedalPressed": alert("Comma Unavailable", "Pedal Pressed", ET.NO_ENTRY, "brakePressed", "chimeDouble", .4, 2., 3.),
"preDriverDistracted": alert("Take Control ", "User Distracted", ET.WARNING, "steerRequired", "chimeDouble", .4, 2., 3.),
"driverDistracted": alert("Take Control to Regain Speed", "User Distracted", ET.WARNING, "steerRequired", "chimeRepeated", .5, .5, .5),
"steerSaturated": alert("Take Control", "Turn Exceeds Limit", ET.WARNING, "steerRequired", "chimeSingle", 1., 2., 3.),
"overheat": alert("Take Control Immediately", "System Overheated", ET.SOFT_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"controlsMismatch": alert("Take Control Immediately", "Controls Mismatch", ET.IMMEDIATE_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"radarCommIssue": alert("Take Control Immediately", "Radar Error: Restart the Car",ET.IMMEDIATE_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"calibrationInvalid": alert("Take Control Immediately", "Calibration Invalid: Reposition Neo and Recalibrate", ET.SOFT_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"calibrationInProgress": alert("Take Control Immediately", "Calibration in Progress: ", ET.SOFT_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"modelCommIssue": alert("Take Control Immediately", "Model Error: Restart the Car",ET.IMMEDIATE_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"controlsFailed": alert("Take Control Immediately", "Controls Failed", ET.IMMEDIATE_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"fcw": alert("", "", ET.WARNING, None, None, .1, .1, .1),
# car errors
"commIssue": alert("Take Control Immediately","Communication Issues", ET.IMMEDIATE_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"steerUnavailable": alert("Take Control Immediately","Steer Error", ET.IMMEDIATE_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"steerTemporarilyUnavailable": alert("Take Control", "Steer Temporarily Unavailable", ET.WARNING, "steerRequired", "chimeRepeated", 1., 2., 3.),
"brakeUnavailable": alert("Take Control Immediately","Brake Error", ET.IMMEDIATE_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"gasUnavailable": alert("Take Control Immediately","Gas Error", ET.IMMEDIATE_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"wrongGear": alert("Take Control Immediately","Gear not D", ET.SOFT_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"reverseGear": alert("Take Control Immediately","Car in Reverse", ET.IMMEDIATE_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"doorOpen": alert("Take Control Immediately","Door Open", ET.SOFT_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"seatbeltNotLatched": alert("Take Control Immediately","Seatbelt Unlatched", ET.SOFT_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"espDisabled": alert("Take Control Immediately","ESP Off", ET.SOFT_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"wrongCarMode": alert("Comma Unavailable","Main Switch Off", ET.NO_ENTRY, None, "chimeDouble", .4, 0., 3.),
"outOfSpace": alert("Comma Unavailable","Out of Space", ET.NO_ENTRY, None, "chimeDouble", .4, 0., 3.),
"dataNeeded": alert("Comma Unavailable","Data needed for calibration. Upload drive, try again", ET.NO_ENTRY, None, "chimeDouble", .4, 0., 3.),
"ethicalDilemma": alert("Take Control Immediately","Ethical Dilemma Detected", ET.IMMEDIATE_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"startup": alert("Always Keep Hands on Wheel","Be Ready to Take Over Any Time", ET.NO_ENTRY, None, None, 0., 0., 15.),
"commIssue": alert("Take Control Immediately","CAN Error: Restart the Car", ET.IMMEDIATE_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"steerUnavailable": alert("Take Control Immediately","Steer Error: Restart the Car", ET.IMMEDIATE_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"steerTempUnavailable": alert("Take Control", "Steer Temporarily Unavailable", ET.WARNING, "steerRequired", "chimeDouble", .4, 2., 3.),
"brakeUnavailable": alert("Take Control Immediately","Brake Error: Restart the Car", ET.IMMEDIATE_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"gasUnavailable": alert("Take Control Immediately","Gas Error: Restart the Car", ET.IMMEDIATE_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"wrongGear": alert("Take Control Immediately","Gear not D", ET.SOFT_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"reverseGear": alert("Take Control Immediately","Car in Reverse", ET.IMMEDIATE_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"doorOpen": alert("Take Control Immediately","Door Open", ET.SOFT_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"seatbeltNotLatched": alert("Take Control Immediately","Seatbelt Unlatched", ET.SOFT_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"espDisabled": alert("Take Control Immediately","ESP Off", ET.SOFT_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"cruiseDisabled": alert("Take Control Immediately","Cruise Is Off", ET.IMMEDIATE_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"wrongCarMode": alert("Comma Unavailable","Main Switch Off", ET.NO_ENTRY, None, "chimeDouble", .4, 0., 3.),
"outOfSpace": alert("Comma Unavailable","Out of Space", ET.NO_ENTRY, None, "chimeDouble", .4, 0., 3.),
"dataNeeded": alert("Comma Unavailable","Data needed for calibration. Upload drive, try again", ET.NO_ENTRY, None, "chimeDouble", .4, 0., 3.),
"ethicalDilemma": alert("Take Control Immediately","Ethical Dilemma Detected", ET.IMMEDIATE_DISABLE, "steerRequired", "chimeRepeated", 1., 3., 3.),
"startup": alert("Always Keep Hands on Wheel","Be Ready to Take Over Any Time", ET.NO_ENTRY, None, None, 0., 0., 15.),
}
def __init__(self):
self.activealerts = []
@@ -70,25 +76,27 @@ class AlertManager(object):
return len(self.activealerts) > 0
def alertShouldSoftDisable(self):
return len(self.activealerts) > 0 and self.activealerts[0].alert_type == ET.SOFT_DISABLE
return len(self.activealerts) > 0 and any(a.alert_type == ET.SOFT_DISABLE for a in self.activealerts)
def alertShouldDisable(self):
return len(self.activealerts) > 0 and self.activealerts[0].alert_type >= ET.IMMEDIATE_DISABLE
return len(self.activealerts) > 0 and any(a.alert_type in [ET.IMMEDIATE_DISABLE, ET.USER_DISABLE] for a in self.activealerts)
def add(self, alert_type, enabled = True):
def add(self, alert_type, enabled=True, extra_text=''):
alert_type = str(alert_type)
this_alert = self.alerts[alert_type]
# downgrade the alert if we aren't enabled
if not enabled and this_alert.alert_type > ET.NO_ENTRY:
this_alert = copy.copy(self.alerts[alert_type])
this_alert.alert_text_2 += extra_text
# downgrade the alert if we aren't enabled, except if it's FCW, which remains the same
# TODO: remove this 'if' by adding more alerts
if not enabled and this_alert.alert_type in [ET.WARNING, ET.SOFT_DISABLE, ET.IMMEDIATE_DISABLE] \
and this_alert != self.alerts['fcw']:
this_alert = alert("Comma Unavailable" if this_alert.alert_text_1 != "" else "", this_alert.alert_text_2, ET.NO_ENTRY, None, "chimeDouble", .4, 0., 3.)
# ignore no entries if we are enabled
if enabled and this_alert.alert_type < ET.WARNING:
if enabled and this_alert.alert_type in [ET.ENABLE, ET.NO_ENTRY]:
return
# if new alert is different, log it
if self.current_alert is None or self.current_alert.alert_text_2 != this_alert.alert_text_2:
# if new alert is higher priority, log it
if self.current_alert is None or this_alert > self.current_alert:
cloudlog.event('alert_add',
alert_type=alert_type,
enabled=enabled)
@@ -101,7 +109,6 @@ class AlertManager(object):
self.alert_start_time = cur_time
self.current_alert = self.activealerts[0]
print self.current_alert
alert_text_1 = ""
alert_text_2 = ""
visual_alert = "none"

View File

@@ -0,0 +1,66 @@
import numpy as np
from common.realtime import sec_since_boot
#Time to collisions greater than 5s are iognored
MAX_TTC = 5.
def calc_ttc(l1):
# if l1 is None, return max ttc immediately
if not l1:
return MAX_TTC
# this function returns the time to collision (ttc), assuming that
# ARel will stay constant TODO: review this assumptions
# change sign to rel quantities as it's going to be easier for calculations
vRel = -l1.vRel
aRel = -l1.aRel
# assuming that closing gap ARel comes from lead vehicle decel,
# then limit ARel so that v_lead will get to zero in no sooner than t_decel.
# This helps underweighting ARel when v_lead is close to zero.
t_decel = 2.
aRel = np.minimum(aRel, l1.vLead/t_decel)
# delta of the quadratic equation to solve for ttc
delta = vRel**2 + 2 * l1.dRel * aRel
# assign an arbitrary high ttc value if there is no solution to ttc
if delta < 0.1 or (np.sqrt(delta) + vRel < 0.1):
ttc = MAX_TTC
else:
ttc = np.minimum(2 * l1.dRel / (np.sqrt(delta) + vRel), MAX_TTC)
return ttc
class ForwardCollisionWarning(object):
def __init__(self, dt):
self.last_active = 0.
self.violation_time = 0.
self.active = False
self.dt = dt # time step
def process(self, CS, AC):
# send an fcw alert if the violation time > violation_thrs
violation_thrs = 0.3 # fcw turns on after a continuous violation for this time
fcw_t_delta = 5. # no more than one fcw alert within this time
a_acc_on = -2.0 # with system on, above this limit of desired decel, we should trigger fcw
a_acc_off = -2.5 # with system off, above this limit of desired decel, we should trigger fcw
ttc_thrs = 2.5 # ttc threshold for fcw
v_fcw_min = 2. # no fcw below 2m/s
steer_angle_th = 40. # deg, no fcw above this steer angle
cur_time = sec_since_boot()
ttc = calc_ttc(AC.l1)
a_fcw = a_acc_on if CS.cruiseState.enabled else a_acc_off
# increase violation time if we want to decelerate quite fast
if AC.l1 and ( \
(CS.vEgo > v_fcw_min) and (CS.vEgo > AC.v_target_lead) and (AC.a_target[0] < a_fcw) \
and not CS.brakePressed and ttc < ttc_thrs and abs(CS.steeringAngle) < steer_angle_th \
and AC.l1.fcw):
self.violation_time = np.minimum(self.violation_time + self.dt, violation_thrs)
else:
self.violation_time = np.maximum(self.violation_time - 2*self.dt, 0)
# fire FCW
self.active = self.violation_time >= violation_thrs and cur_time > (self.last_active + fcw_t_delta)
if self.active:
self.last_active = cur_time

View File

@@ -1,6 +1,6 @@
import math
import numpy as np
from common.numpy_fast import clip
from common.numpy_fast import clip, interp
def calc_curvature(v_ego, angle_steers, CP, angle_offset=0):
deg_to_rad = np.pi/180.
@@ -8,15 +8,28 @@ def calc_curvature(v_ego, angle_steers, CP, angle_offset=0):
curvature = angle_steers_rad/(CP.steerRatio * CP.wheelBase * (1. + CP.slipFactor * v_ego**2))
return curvature
def calc_d_lookahead(v_ego):
_K_CURV_V = [1., 0.6]
_K_CURV_BP = [0., 0.002]
def calc_d_lookahead(v_ego, d_poly):
#*** this function computes how far too look for lateral control
# howfar we look ahead is function of speed
# howfar we look ahead is function of speed and how much curvy is the path
offset_lookahead = 1.
coeff_lookahead = 4.4
# sqrt on speed is needed to keep, for a given curvature, the y_offset
k_lookahead = 7.
# integrate abs value of second derivative of poly to get a measure of path curvature
pts_len = 50. # m
if len(d_poly)>0:
pts = np.polyval([6*d_poly[0], 2*d_poly[1]], np.arange(0, pts_len))
else:
pts = 0.
curv = np.sum(np.abs(pts))/pts_len
k_curv = interp(curv, _K_CURV_BP, _K_CURV_V)
# sqrt on speed is needed to keep, for a given curvature, the y_offset
# proportional to speed. Indeed, y_offset is prop to d_lookahead^2
# 26m at 25m/s
d_lookahead = offset_lookahead + math.sqrt(max(v_ego, 0)) * coeff_lookahead
# 36m at 25m/s
d_lookahead = offset_lookahead + math.sqrt(max(v_ego, 0)) * k_lookahead * k_curv
return d_lookahead
def calc_lookahead_offset(v_ego, angle_steers, d_lookahead, CP, angle_offset):
@@ -31,7 +44,7 @@ def pid_lateral_control(v_ego, y_actual, y_des, Ui_steer, steer_max,
steer_override, sat_count, enabled, Kp, Ki, rate):
sat_count_rate = 1./rate
sat_count_limit = 0.8 # after 0.8s of continuous saturation, an alert will be sent
sat_count_limit = 0.8 # after 0.8s of continuous saturation, an alert will be sent
error_steer = y_des - y_actual
Ui_unwind_speed = 0.3/rate #.3 per second
@@ -101,8 +114,8 @@ class LatControl(object):
steer_max = 1.0
# how far we look ahead is function of speed
d_lookahead = calc_d_lookahead(v_ego)
# how far we look ahead is function of speed and desired path
d_lookahead = calc_d_lookahead(v_ego, d_poly)
# calculate actual offset at the lookahead point
self.y_actual, _ = calc_lookahead_offset(v_ego, angle_steers,

View File

@@ -39,21 +39,35 @@ def calc_desired_path(l_poly, r_poly, p_poly, l_prob, r_prob, p_prob, speed):
d_poly = list((c_poly*c_prob + p_poly*p_prob*p_weight ) / (c_prob + p_prob*p_weight))
return d_poly, c_poly, c_prob
class PathPlanner(object):
class OptPathPlanner(object):
def __init__(self, model):
self.model = model
self.dead = True
self.d_poly = [0., 0., 0., 0.]
self.last_model = 0.
self.logMonoTime = 0
self._path_pinv = compute_path_pinv()
def update(self, cur_time, v_ego, md):
if md is not None:
# simple compute of the center of the lane
pts = [(x+y)/2 for x,y in zip(md.model.leftLane.points, md.model.rightLane.points)]
self.d_poly = model_polyfit(pts, self._path_pinv)
self.last_model = cur_time
self.dead = False
elif cur_time - self.last_model > 0.5:
self.dead = True
class PathPlanner(object):
def __init__(self):
self.dead = True
self.d_poly = [0., 0., 0., 0.]
self.last_model = 0.
self.lead_dist, self.lead_prob, self.lead_var = 0, 0, 1
self._path_pinv = compute_path_pinv()
def update(self, cur_time, v_ego):
md = messaging.recv_sock(self.model)
def update(self, cur_time, v_ego, md):
if md is not None:
self.logMonoTime = md.logMonoTime
p_poly = model_polyfit(md.model.path.points, self._path_pinv) # predicted path
l_poly = model_polyfit(md.model.leftLane.points, self._path_pinv) # left line
r_poly = model_polyfit(md.model.rightLane.points, self._path_pinv) # right line

View File

@@ -0,0 +1,84 @@
#!/usr/bin/env python
import os
import zmq
import numpy as np
import selfdrive.messaging as messaging
from selfdrive.services import service_list
from common.realtime import sec_since_boot
from common.params import Params
from selfdrive.swaglog import cloudlog
from cereal import car
from selfdrive.controls.lib.pathplanner import OptPathPlanner
from selfdrive.controls.lib.pathplanner import PathPlanner
from selfdrive.controls.lib.adaptivecruise import AdaptiveCruise
from selfdrive.controls.lib.fcw import ForwardCollisionWarning
_DT = 0.01 # 100Hz
class Planner(object):
def __init__(self, CP):
context = zmq.Context()
self.CP = CP
self.live20 = messaging.sub_sock(context, service_list['live20'].port)
self.model = messaging.sub_sock(context, service_list['model'].port)
self.plan = messaging.pub_sock(context, service_list['plan'].port)
self.last_md_ts = 0
self.last_l20_ts = 0
if os.getenv("OPT") is not None:
self.PP = OptPathPlanner(self.model)
else:
self.PP = PathPlanner()
self.AC = AdaptiveCruise()
self.FCW = ForwardCollisionWarning(_DT)
# this runs whenever we get a packet that can change the plan
def update(self, CS, LoC):
cur_time = sec_since_boot()
md = messaging.recv_sock(self.model)
if md is not None:
self.last_md_ts = md.logMonoTime
l20 = messaging.recv_sock(self.live20)
if l20 is not None:
self.last_l20_ts = l20.logMonoTime
self.PP.update(cur_time, CS.vEgo, md)
# LoC.v_pid -> CS.vEgo
# TODO: is this change okay?
self.AC.update(cur_time, CS.vEgo, CS.steeringAngle, LoC.v_pid, self.CP, l20)
# **** send the plan ****
plan_send = messaging.new_message()
plan_send.init('plan')
plan_send.plan.mdMonoTime = self.last_md_ts
plan_send.plan.l20MonoTime = self.last_l20_ts
# lateral plan
plan_send.plan.lateralValid = not self.PP.dead
if plan_send.plan.lateralValid:
plan_send.plan.dPoly = map(float, self.PP.d_poly)
# longitudal plan
plan_send.plan.longitudinalValid = not self.AC.dead
if plan_send.plan.longitudinalValid:
plan_send.plan.vTarget = float(self.AC.v_target_lead)
plan_send.plan.aTargetMin = float(self.AC.a_target[0])
plan_send.plan.aTargetMax = float(self.AC.a_target[1])
plan_send.plan.jerkFactor = float(self.AC.jerk_factor)
plan_send.plan.hasLead = self.AC.has_lead
# compute risk of collision events: fcw
self.FCW.process(CS, self.AC)
plan_send.plan.fcw = bool(self.FCW.active)
self.plan.send(plan_send.to_bytes())
return plan_send

View File

@@ -205,7 +205,7 @@ class Cluster(object):
lead.vLeadK = float(self.vLeadK)
lead.aLeadK = float(self.aLeadK)
lead.status = True
lead.fcw = False
lead.fcw = self.is_potential_fcw()
def __str__(self):
ret = "x: %7.2f y: %7.2f v: %7.2f a: %7.2f" % (self.dRel, self.yRel, self.vRel, self.aRel)
@@ -240,18 +240,18 @@ class Cluster(object):
d_path = max(d_path + lat_corr, 0)
if d_path < 1.5 and not self.stationary and not self.oncoming:
return True
else:
return False
return d_path < 1.5 and not self.stationary and not self.oncoming
def is_potential_lead2(self, lead_clusters):
if len(lead_clusters) > 0:
lead_cluster = lead_clusters[0]
# check if the new lead is too close and roughly at the same speed of the first lead: it might just be the second axle of the same vehicle
if (self.dRel - lead_cluster.dRel) < 8. and abs(self.vRel - lead_cluster.vRel) < 1.:
return False
else:
return True
# check if the new lead is too close and roughly at the same speed of the first lead:
# it might just be the second axle of the same vehicle
return (self.dRel - lead_cluster.dRel) > 8. or abs(self.vRel - lead_cluster.vRel) > 1.
else:
return False
def is_potential_fcw(self):
# is this cluster trustrable enough for triggering fcw?
# fcw can trigger only on clusters that have been fused vision model for at least 20 frames
return self.vision_cnt >= 20

View File

@@ -1,80 +0,0 @@
#!/usr/bin/env python
import os
import zmq
import numpy as np
import selfdrive.messaging as messaging
from selfdrive.services import service_list
from common.realtime import sec_since_boot, set_realtime_priority
from common.params import Params
from selfdrive.swaglog import cloudlog
from cereal import car
from selfdrive.controls.lib.pathplanner import PathPlanner
from selfdrive.controls.lib.adaptivecruise import AdaptiveCruise
def plannerd_thread(gctx):
context = zmq.Context()
poller = zmq.Poller()
carstate = messaging.sub_sock(context, service_list['carState'].port, poller)
live20 = messaging.sub_sock(context, service_list['live20'].port)
model = messaging.sub_sock(context, service_list['model'].port)
plan = messaging.pub_sock(context, service_list['plan'].port)
# wait for stats about the car to come in from controls
cloudlog.info("plannerd is waiting for CarParams")
CP = car.CarParams.from_bytes(Params().get("CarParams", block=True))
cloudlog.info("plannerd got CarParams")
CS = None
PP = PathPlanner(model)
AC = AdaptiveCruise(live20)
# start the loop
set_realtime_priority(2)
# this runs whenever we get a packet that can change the plan
while True:
polld = poller.poll(timeout=1000)
for sock, mode in polld:
if mode != zmq.POLLIN or sock != carstate:
continue
cur_time = sec_since_boot()
CS = messaging.recv_sock(carstate).carState
PP.update(cur_time, CS.vEgo)
# LoC.v_pid -> CS.vEgo
# TODO: is this change okay?
AC.update(cur_time, CS.vEgo, CS.steeringAngle, CS.vEgo, CP)
# **** send the plan ****
plan_send = messaging.new_message()
plan_send.init('plan')
# lateral plan
plan_send.plan.lateralValid = not PP.dead
if plan_send.plan.lateralValid:
plan_send.plan.dPoly = map(float, PP.d_poly)
# longitudal plan
plan_send.plan.longitudinalValid = not AC.dead
if plan_send.plan.longitudinalValid:
plan_send.plan.vTarget = float(AC.v_target_lead)
plan_send.plan.aTargetMin = float(AC.a_target[0])
plan_send.plan.aTargetMax = float(AC.a_target[1])
plan_send.plan.jerkFactor = float(AC.jerk_factor)
plan.send(plan_send.to_bytes())
def main(gctx=None):
plannerd_thread(gctx)
if __name__ == "__main__":
main()

View File

@@ -20,6 +20,7 @@ from common.params import Params
from common.realtime import sec_since_boot, set_realtime_priority, Ratekeeper
from common.kalman.ekf import EKF, SimpleSensor
VISION_ONLY = False
#vision point
DIMSV = 2
@@ -62,9 +63,12 @@ def radard_thread(gctx=None):
model = messaging.sub_sock(context, service_list['model'].port)
live100 = messaging.sub_sock(context, service_list['live100'].port)
PP = PathPlanner(model)
PP = PathPlanner()
RI = RadarInterface()
last_md_ts = 0
last_l100_ts = 0
# *** publish live20 and liveTracks
live20 = messaging.pub_sock(context, service_list['live20'].port)
liveTracks = messaging.pub_sock(context, service_list['liveTracks'].port)
@@ -109,18 +113,24 @@ def radard_thread(gctx=None):
v_ego_array = np.append(v_ego_array, [[v_ego], [float(rk.frame)/rate]], 1)
v_ego_array = v_ego_array[:, 1:]
last_l100_ts = l100.logMonoTime
if v_ego is None:
continue
md = messaging.recv_sock(model)
if md is not None:
last_md_ts = md.logMonoTime
# *** get path prediction from the model ***
PP.update(sec_since_boot(), v_ego)
PP.update(sec_since_boot(), v_ego, md)
# run kalman filter only if prob is high enough
if PP.lead_prob > 0.7:
ekfv.update(speedSensorV.read(PP.lead_dist, covar=PP.lead_var))
ekfv.predict(tsv)
ar_pts[VISION_POINT] = (float(ekfv.state[XV]), np.polyval(PP.d_poly, float(ekfv.state[XV])),
float(ekfv.state[SPEEDV]), np.nan, PP.logMonoTime, np.nan, sec_since_boot())
float(ekfv.state[SPEEDV]), np.nan, last_md_ts, np.nan, sec_since_boot())
else:
ekfv.state[XV] = PP.lead_dist
ekfv.covar = (np.diag([PP.lead_var, ekfv.var_init]))
@@ -142,7 +152,9 @@ def radard_thread(gctx=None):
# *** compute the tracks ***
for ids in ar_pts:
# ignore the vision point for now
if ids == VISION_POINT:
if ids == VISION_POINT and not VISION_ONLY:
continue
elif ids != VISION_POINT and VISION_ONLY:
continue
rpt = ar_pts[ids]
@@ -212,8 +224,9 @@ def radard_thread(gctx=None):
# *** publish live20 ***
dat = messaging.new_message()
dat.init('live20')
dat.live20.mdMonoTime = PP.logMonoTime
dat.live20.mdMonoTime = last_md_ts
dat.live20.canMonoTimes = list(rr.canMonoTimes)
dat.live20.l100MonoTime = last_l100_ts
if lead_len > 0:
lead_clusters[0].toLive20(dat.live20.leadOne)
if lead2_len > 0:

View File

@@ -1,17 +1,17 @@
#!/usr/bin/env python
from evdev import InputDevice
from select import select
import time
import numpy as np
import zmq
from evdev import InputDevice
from select import select
from cereal import car
from common.realtime import Ratekeeper
import selfdrive.messaging as messaging
from selfdrive.services import service_list
from common.realtime import Ratekeeper
from selfdrive.car import get_car
from common.fingerprints import fingerprint
if __name__ == "__main__":
# ***** connect to joystick *****
@@ -27,10 +27,7 @@ if __name__ == "__main__":
logcan = messaging.sub_sock(context, service_list['can'].port)
sendcan = messaging.pub_sock(context, service_list['sendcan'].port)
CP = fingerprint(logcan)
exec('from selfdrive.car.'+CP.carName+'.interface import CarInterface')
CI = CarInterface(CP, logcan, sendcan)
CI, CP = get_car(logcan, sendcan)
rk = Ratekeeper(100)
@@ -60,7 +57,7 @@ if __name__ == "__main__":
# **** handle car ****
CS = CI.update()
print CS
#print CS
CC = car.CarControl.new_message()
@@ -68,7 +65,7 @@ if __name__ == "__main__":
CC.gas = float(np.clip(-axis_values[1], 0, 1.0))
CC.brake = float(np.clip(axis_values[1], 0, 1.0))
CC.steeringTorque = float(axis_values[0])
CC.steeringTorque = float(-axis_values[0])
CC.hudControl.speedVisible = bool(button_values[1])
CC.hudControl.lanesVisible = bool(button_values[2])
@@ -83,7 +80,7 @@ if __name__ == "__main__":
CC.hudControl.visualAlert = "none"
CC.hudControl.audibleAlert = "none"
print CC
#print CC
if not CI.apply(CC):
print "CONTROLS FAILED"

View File

@@ -5,7 +5,7 @@ import zmq
import selfdrive.messaging as messaging
from selfdrive.services import service_list
from common.fingerprints import fingerprint
from selfdrive.car import get_car
def bpressed(CS, btype):
for b in CS.buttonEvents:
@@ -17,10 +17,7 @@ def test_loop():
context = zmq.Context()
logcan = messaging.sub_sock(context, service_list['can'].port)
CP = fingerprint(logcan)
exec('from selfdrive.car.'+CP.carName+'.interface import CarInterface')
CI = CarInterface(CP, logcan, None)
CI, CP = get_car(logcan)
state = 0

View File

@@ -1,4 +1,4 @@
import os
ROOT = '/sdcard/realdata/'
ROOT = '/data/media/0/realdata/'
SEGMENT_LENGTH = 60

Binary file not shown.

View File

@@ -117,7 +117,12 @@ class Uploader(object):
if name in ["rlog", "rlog.bz2"]:
return (key, fn, 0)
# then upload camera files no not on wifi
# then upload compressed camera file
for name, key, fn in self.gen_upload_files():
if name in ["fcamera.hevc"]:
return (key, fn, 1)
# then upload other files
for name, key, fn in self.gen_upload_files():
if not name.endswith('.lock') and not name.endswith(".tmp"):
return (key, fn, 1)
@@ -131,10 +136,10 @@ class Uploader(object):
url_resp_json = json.loads(url_resp.text)
url = url_resp_json['url']
headers = url_resp_json['headers']
cloudlog.info({"upload_url v1.1", url, str(headers)})
cloudlog.info("upload_url v1.1 %s %s", url, str(headers))
if fake_upload:
print "*** WARNING, THIS IS A FAKE UPLOAD TO %s ***" % url
cloudlog.info("*** WARNING, THIS IS A FAKE UPLOAD TO %s ***" % url)
class FakeResponse(object):
def __init__(self):
self.status_code = 200
@@ -208,7 +213,7 @@ class Uploader(object):
cloudlog.info("uploading %r", fn)
# stat = self.killable_upload(key, fn)
stat = self.normal_upload(key, fn)
if stat is not None and stat.status_code == 200:
if stat is not None and stat.status_code in (200, 201):
cloudlog.event("upload_success", key=key, fn=fn, sz=sz)
os.unlink(fn) # delete the file
success = True
@@ -254,7 +259,7 @@ def uploader_fn(exit_event):
else:
cloudlog.info("backoff %r", backoff)
time.sleep(backoff + random.uniform(0, backoff))
backoff *= 2
backoff = min(backoff*2, 120)
cloudlog.info("upload done, success=%r", success)
time.sleep(5)

View File

@@ -7,7 +7,7 @@ import selfdrive.messaging as messaging
def main(gctx):
# setup logentries. we forward log messages to it
le_token = "e8549616-0798-4d7e-a2ca-2513ae81fa17"
le_handler = LogentriesHandler(le_token, use_tls=False)
le_handler = LogentriesHandler(le_token, use_tls=False, verbose=False)
le_level = 20 #logging.INFO

View File

@@ -3,7 +3,9 @@ import os
# check if NEOS update is required
while 1:
if (not os.path.isfile("/VERSION") or int(open("/VERSION").read()) < 3) and not os.path.isfile("/sdcard/noupdate"):
if ((not os.path.isfile("/VERSION")
or int(open("/VERSION").read()) < 3)
and not os.path.isfile("/data/media/0/noupdate")):
os.system("curl -o /tmp/updater https://openpilot.comma.ai/updater && chmod +x /tmp/updater && /tmp/updater")
else:
break
@@ -34,11 +36,12 @@ from common.params import Params
from selfdrive.loggerd.config import ROOT
BASEDIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../")
# comment out anything you don't want to run
managed_processes = {
"uploader": "selfdrive.loggerd.uploader",
"controlsd": "selfdrive.controls.controlsd",
"plannerd": "selfdrive.controls.plannerd",
"radard": "selfdrive.controls.radard",
"loggerd": ("loggerd", ["./loggerd"]),
"logmessaged": "selfdrive.logmessaged",
@@ -51,6 +54,8 @@ managed_processes = {
"sensord": ("sensord", ["./sensord"]), }
running = {}
def get_running():
return running
# due to qualcomm kernel bugs SIGKILLing visiond sometimes causes page table corruption
unkillable_processes = ['visiond']
@@ -60,7 +65,6 @@ interrupt_processes = []
car_started_processes = [
'controlsd',
'plannerd',
'loggerd',
'sensord',
'radard',
@@ -112,7 +116,7 @@ def start_managed_process(name):
running[name] = Process(name=name, target=launcher, args=(proc, gctx))
else:
pdir, pargs = proc
cwd = os.path.dirname(os.path.realpath(__file__))
cwd = os.path.join(BASEDIR, "selfdrive")
if pdir is not None:
cwd = os.path.join(cwd, pdir)
cloudlog.info("starting process %s" % name)
@@ -183,15 +187,34 @@ def manager_init():
cloudlog.info("dongle id is " + dongle_id)
os.environ['DONGLE_ID'] = dongle_id
cloudlog.bind_global(dongle_id=dongle_id, version=version)
crash.bind_user(id=dongle_id)
crash.bind_extra(version=version)
dirty = subprocess.call(["git", "diff-index", "--quiet", "origin/release", "--"]) != 0
cloudlog.info("dirty is %d" % dirty)
if not dirty:
os.environ['CLEAN'] = '1'
os.system("mkdir -p "+ROOT)
cloudlog.bind_global(dongle_id=dongle_id, version=version, dirty=dirty)
crash.bind_user(id=dongle_id)
crash.bind_extra(version=version, dirty=dirty)
os.umask(0)
try:
os.mkdir(ROOT, 0777)
except OSError:
pass
# set gctx
gctx = {}
def system(cmd):
try:
cloudlog.info("running %s" % cmd)
subprocess.check_output(cmd, stderr=subprocess.STDOUT, shell=True)
except subprocess.CalledProcessError, e:
cloudlog.event("running failed",
cmd=e.cmd,
output=e.output,
returncode=e.returncode)
def manager_thread():
global baseui_running
@@ -217,14 +240,11 @@ def manager_thread():
# flash the device
if os.getenv("NOPROG") is None:
# checkout the matching panda repo
rootdir = os.path.dirname(os.path.abspath(__file__))
os.system("cd %s && git submodule init && git submodule update" % rootdir)
# flash the board
boarddir = os.path.dirname(os.path.abspath(__file__))+"/../panda/board/"
boarddir = os.path.join(BASEDIR, "panda/board/")
mkfile = "Makefile" if panda else "Makefile.legacy"
print "using", mkfile
os.system("cd %s && make -f %s" % (boarddir, mkfile))
system("cd %s && make -f %s" % (boarddir, mkfile))
start_managed_process("boardd")
@@ -322,8 +342,12 @@ def get_installed_apks():
# optional, build the c++ binaries and preimport the python for speed
def manager_prepare():
# update submodules
system("cd %s && git submodule init panda opendbc pyextra" % BASEDIR)
system("cd %s && git submodule update panda opendbc pyextra" % BASEDIR)
# build cereal first
subprocess.check_call(["make", "-j4"], cwd="../cereal")
subprocess.check_call(["make", "-j4"], cwd=os.path.join(BASEDIR, "cereal"))
# build all processes
os.chdir(os.path.dirname(os.path.abspath(__file__)))
@@ -346,14 +370,14 @@ def manager_prepare():
# install apks
installed = get_installed_apks()
for app in os.listdir("../apk/"):
for app in os.listdir(os.path.join(BASEDIR, "apk/")):
if ".apk" in app:
app = app.split(".apk")[0]
if app not in installed:
installed[app] = None
cloudlog.info("installed apks %s" % (str(installed), ))
for app in installed:
apk_path = "../apk/"+app+".apk"
apk_path = os.path.join(BASEDIR, "apk/"+app+".apk")
if os.path.isfile(apk_path):
h1 = hashlib.sha1(open(apk_path).read()).hexdigest()
h2 = None
@@ -419,9 +443,27 @@ def main():
params = Params()
params.manager_start()
manager_init()
manager_prepare()
# set unset params
if params.get("IsMetric") is None:
params.put("IsMetric", "0")
if params.get("IsRearViewMirror") is None:
params.put("IsRearViewMirror", "1")
# put something on screen while we set things up
if os.getenv("PREPAREONLY") is not None:
spinner_proc = None
else:
spinner_proc = subprocess.Popen(["./spinner", "loading openpilot..."],
cwd=os.path.join(BASEDIR, "selfdrive", "ui", "spinner"),
close_fds=True)
try:
manager_init()
manager_prepare()
finally:
if spinner_proc:
spinner_proc.terminate()
if os.getenv("PREPAREONLY") is not None:
sys.exit(0)

View File

@@ -1,14 +1,21 @@
#!/usr/bin/env python
import os
import numpy as np
from selfdrive.car.honda.can_parser import CANParser
from selfdrive.can.parser import CANParser as CANParserC
from selfdrive.boardd.boardd import can_capnp_to_can_list
from cereal import car
from common.realtime import sec_since_boot
import zmq
from selfdrive.services import service_list
import selfdrive.messaging as messaging
NEW_CAN = os.getenv("OLD_CAN") is None
def _create_radard_can_parser():
dbc_f = 'acura_ilx_2016_nidec.dbc'
radar_messages = range(0x430, 0x43A) + range(0x440, 0x446)
@@ -17,7 +24,10 @@ def _create_radard_can_parser():
[255] * 16 + [1] * 16 + [0] * 16 + [0] * 16)
checks = zip(radar_messages, [20]*16)
return CANParser(dbc_f, signals, checks)
if NEW_CAN:
return CANParserC(os.path.splitext(dbc_f)[0], signals, checks, 1)
else:
return CANParser(dbc_f, signals, checks)
class RadarInterface(object):
def __init__(self):
@@ -33,19 +43,28 @@ class RadarInterface(object):
def update(self):
canMonoTimes = []
can_pub_radar = []
# TODO: can hang if no packets show up
while 1:
for a in messaging.drain_sock(self.logcan, wait_for_one=True):
canMonoTimes.append(a.logMonoTime)
can_pub_radar.extend(can_capnp_to_can_list(a.can, [1, 3]))
if NEW_CAN:
updated_messages = set()
while 1:
tm = int(sec_since_boot() * 1e9)
updated_messages.update(self.rcp.update(tm, True))
if 0x445 in updated_messages:
break
else:
can_pub_radar = []
# only run on the 0x445 packets, used for timing
if any(x[0] == 0x445 for x in can_pub_radar):
break
# TODO: can hang if no packets show up
while 1:
for a in messaging.drain_sock(self.logcan, wait_for_one=True):
canMonoTimes.append(a.logMonoTime)
can_pub_radar.extend(can_capnp_to_can_list(a.can, [1, 3]))
updated_messages = self.rcp.update_can(can_pub_radar)
# only run on the 0x445 packets, used for timing
if any(x[0] == 0x445 for x in can_pub_radar):
break
updated_messages = self.rcp.update_can(can_pub_radar)
ret = car.RadarState.new_message()
errors = []
@@ -56,6 +75,7 @@ class RadarInterface(object):
for ii in updated_messages:
cpt = self.rcp.vl[ii]
#print cpt
if cpt['LONG_DIST'] < 255:
if ii not in self.pts or cpt['NEW_TRACK']:
self.pts[ii] = car.RadarState.RadarPoint.new_message()

Binary file not shown.

View File

@@ -41,6 +41,9 @@ navUpdate: [8028, true]
qcomGnss: [8029, true]
lidarPts: [8030, true]
procLog: [8031, true]
gpsLocationExternal: [8032, true]
ubloxGnss: [8033, true]
testModel: [8040, false]
# manager -- base process to manage starting and stopping of all others
# subscribes: health

View File

@@ -5,7 +5,7 @@ import struct
import zmq
import numpy as np
from dbcs import DBC_PATH
from opendbc import DBC_PATH
from common.realtime import Ratekeeper
@@ -143,6 +143,10 @@ class Plant(object):
self.cp = get_car_can_parser()
def close(self):
Plant.logcan.close()
Plant.model.close()
def speed_sensor(self, speed):
if speed<0.3:
return 0
@@ -152,7 +156,7 @@ class Plant(object):
def current_time(self):
return float(self.rk.frame) / self.rate
def step(self, v_lead=0.0, cruise_buttons=None, grade=0.0):
def step(self, v_lead=0.0, cruise_buttons=None, grade=0.0, publish_model = True):
# dbc_f, sgs, ivs, msgs, cks_msgs, frqs = initialize_can_struct(self.civic, self.brake_only)
cp2 = get_can_parser(fake_car_params())
sgs = cp2._sgs
@@ -198,7 +202,7 @@ class Plant(object):
acceleration = 0
# ******** lateral ********
self.angle_steer -= steer_torque
self.angle_steer -= (steer_torque/10.0) * self.ts
# *** radar model ***
if self.lead_relevancy:
@@ -228,7 +232,6 @@ class Plant(object):
# interceptor_gas
0,0]
# TODO: publish each message at proper frequency
can_msgs = []
for msg in set(msgs):
@@ -261,18 +264,22 @@ class Plant(object):
Plant.logcan.send(can_list_to_can_capnp(can_msgs).to_bytes())
# ******** publish a fake model going straight ********
md = messaging.new_message()
md.init('model')
md.model.frameId = 0
for x in [md.model.path, md.model.leftLane, md.model.rightLane]:
x.points = [0.0]*50
x.prob = 1.0
x.std = 1.0
# fake values?
Plant.model.send(md.to_bytes())
if publish_model:
md = messaging.new_message()
md.init('model')
md.model.frameId = 0
for x in [md.model.path, md.model.leftLane, md.model.rightLane]:
x.points = [0.0]*50
x.prob = 1.0
x.std = 1.0
# fake values?
Plant.model.send(md.to_bytes())
# ******** update prevs ********
self.speed = speed
self.distance = distance
self.distance_lead = distance_lead
self.speed_prev = speed
self.distance_prev = distance
self.distance_lead_prev = distance_lead

View File

@@ -1,12 +1,14 @@
#!/bin/bash
export OPTEST=1
export OLD_CAN=1
pushd ../../controls
./controlsd.py &
pid1=$!
./radard.py &
pid2=$!
./plannerd.py &
pid3=$!
trap "trap - SIGTERM && kill $pid1 && kill $pid2 && kill $pid3" SIGINT SIGTERM EXIT
trap "trap - SIGTERM && kill $pid1 && kill $pid2" SIGINT SIGTERM EXIT
popd
mkdir -p out
MPLBACKEND=svg ./runtracks.py out

View File

@@ -0,0 +1,102 @@
import os
os.environ['FAKEUPLOAD'] = "1"
from common.testing import phone_only
from selfdrive.manager import manager_init, manager_prepare
from selfdrive.manager import start_managed_process, kill_managed_process, get_running
from selfdrive.manager import manage_baseui
from selfdrive.config import CruiseButtons
from functools import wraps
import time
DID_INIT = False
# must run first
@phone_only
def test_manager_prepare():
global DID_INIT
manager_init()
manager_prepare()
DID_INIT = True
def with_processes(processes):
def wrapper(func):
@wraps(func)
def wrap():
if not DID_INIT:
test_manager_prepare()
# start and assert started
[start_managed_process(p) for p in processes]
assert all(get_running()[name].exitcode is None for name in processes)
# call the function
func()
# assert processes are still started
assert all(get_running()[name].exitcode is None for name in processes)
# kill and assert all stopped
[kill_managed_process(p) for p in processes]
assert len(get_running()) == 0
return wrap
return wrapper
@phone_only
@with_processes(['controlsd', 'radard'])
def test_controls():
from selfdrive.test.plant.plant import Plant
# start the fake car for 2 seconds
plant = Plant(100)
for i in range(200):
if plant.rk.frame >= 20 and plant.rk.frame <= 25:
cruise_buttons = CruiseButtons.RES_ACCEL
# rolling forward
assert plant.speed > 0
else:
cruise_buttons = 0
plant.step(cruise_buttons = cruise_buttons)
plant.close()
# assert that we stopped
assert plant.speed == 0.0
@phone_only
@with_processes(['loggerd', 'logmessaged', 'tombstoned', 'proclogd', 'logcatd'])
def test_logging():
print "LOGGING IS SET UP"
time.sleep(1.0)
@phone_only
@with_processes(['visiond'])
def test_visiond():
print "VISIOND IS SET UP"
time.sleep(5.0)
@phone_only
@with_processes(['sensord'])
def test_sensord():
print "SENSORS ARE SET UP"
time.sleep(1.0)
@phone_only
@with_processes(['ui'])
def test_ui():
print "RUNNING UI"
time.sleep(1.0)
# will have one thing to upload if loggerd ran
# TODO: assert it actually uploaded
@phone_only
@with_processes(['uploader'])
def test_uploader():
print "UPLOADER"
time.sleep(10.0)
@phone_only
def test_baseui():
manage_baseui(True)
time.sleep(10.0)
manage_baseui(False)

View File

@@ -41,7 +41,7 @@ def report_tombstone(fn, client):
message += parsedict.get('abort') or ''
else:
parsedict = {}
message = fn
message = fn+"\n"+dat[:1024]
client.send(
event_id=uuid.uuid4().hex,
@@ -56,6 +56,7 @@ def report_tombstone(fn, client):
'backtrace': parsedict.get('backtrace'),
'logtail': logtail,
'version': version,
'dirty': not bool(os.environ.get('CLEAN')),
},
user={'id': os.environ.get('DONGLE_ID')},
message=message,

1
selfdrive/ui/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
ui

View File

@@ -36,6 +36,7 @@ OBJS = ui.o \
../common/params.o \
../common/util.o \
../common/touch.o \
../common/swaglog.o \
$(PHONELIBS)/nanovg/nanovg.o \
$(PHONELIBS)/json/src/json.o \
$(CEREAL_OBJS)

BIN
selfdrive/ui/spinner/spinner Executable file

Binary file not shown.

View File

@@ -0,0 +1,77 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <math.h>
#include <unistd.h>
#include <assert.h>
#include <GLES3/gl3.h>
#include <EGL/eglext.h>
#include "nanovg.h"
#define NANOVG_GLES3_IMPLEMENTATION
#include "nanovg_gl.h"
#include "nanovg_gl_utils.h"
#include "common/framebuffer.h"
int main(int argc, char** argv) {
int err;
const char* spintext = NULL;
if (argc >= 2) {
spintext = argv[1];
}
// spinner
int fb_w, fb_h;
EGLDisplay display;
EGLSurface surface;
FramebufferState *fb = framebuffer_init("spinner", 0x00001000, false,
&display, &surface, &fb_w, &fb_h);
assert(fb);
NVGcontext *vg = nvgCreateGLES3(NVG_ANTIALIAS | NVG_STENCIL_STROKES);
assert(vg);
int font = nvgCreateFont(vg, "Bold", "../../assets/courbd.ttf");
assert(font >= 0);
for (int cnt = 0; ; cnt++) {
glClearColor(0.1, 0.1, 0.1, 1.0);
glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
nvgBeginFrame(vg, fb_w, fb_h, 1.0f);
for (int k=0; k<3; k++) {
float ang = (2*M_PI * (float)cnt / 120.0) + (k / 3.0) * 2*M_PI;
nvgBeginPath(vg);
nvgStrokeColor(vg, nvgRGBA(255, 255, 255, 255));
nvgStrokeWidth(vg, 5);
nvgMoveTo(vg, fb_w/2 + 50 * cosf(ang), fb_h/2 + 50 * sinf(ang));
nvgLineTo(vg, fb_w/2 + 15 * cosf(ang), fb_h/2 + 15 * sinf(ang));
nvgMoveTo(vg, fb_w/2 - 15 * cosf(ang), fb_h/2 - 15 * sinf(ang));
nvgLineTo(vg, fb_w/2 - 50 * cosf(ang), fb_h/2 - 50 * sinf(ang));
nvgStroke(vg);
}
if (spintext) {
nvgTextAlign(vg, NVG_ALIGN_CENTER | NVG_ALIGN_TOP);
nvgFontSize(vg, 96.0f);
nvgText(vg, fb_w / 2, fb_h*2/3, spintext, NULL);
}
nvgEndFrame(vg);
eglSwapBuffers(display, surface);
assert(glGetError() == GL_NO_ERROR);
}
return 0;
}

View File

@@ -20,6 +20,7 @@
#include "common/timing.h"
#include "common/util.h"
#include "common/swaglog.h"
#include "common/mat.h"
#include "common/glutil.h"
@@ -60,6 +61,7 @@ typedef struct UIScene {
uint8_t *bgr_front_ptr;
int front_box_x, front_box_y, front_box_width, front_box_height;
uint64_t alert_ts;
char alert_text1[1024];
char alert_text2[1024];
@@ -69,8 +71,6 @@ typedef struct UIScene {
typedef struct UIState {
pthread_mutex_t lock;
TouchState touch;
FramebufferState *fb;
int fb_w, fb_h;
@@ -122,6 +122,8 @@ typedef struct UIState {
bool awake;
int awake_timeout;
bool is_metric;
} UIState;
static void set_awake(UIState *s, bool awake) {
@@ -133,7 +135,7 @@ static void set_awake(UIState *s, bool awake) {
s->awake = awake;
if (awake) {
printf("awake normal\n");
LOG("awake normal");
framebuffer_set_power(s->fb, HWC_POWER_MODE_NORMAL);
// can't hurt
@@ -143,7 +145,7 @@ static void set_awake(UIState *s, bool awake) {
fclose(f);
}
} else {
printf("awake off\n");
LOG("awake off");
framebuffer_set_power(s->fb, HWC_POWER_MODE_OFF);
}
}
@@ -228,10 +230,8 @@ static void ui_init(UIState *s) {
s->ipc_fd = -1;
touch_init(&s->touch);
// init display
s->fb = framebuffer_init("ui", 0x00001000,
s->fb = framebuffer_init("ui", 0x00010000, true,
&s->display, &s->surface, &s->fb_w, &s->fb_h);
assert(s->fb);
set_awake(s, true);
@@ -342,6 +342,13 @@ static void ui_init_vision(UIState *s, const VisionStreamBufs back_bufs,
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0,
}};
char *value;
const int result = read_db_value("/data/params", "IsMetric", &value, NULL);
if (result == 0) {
s->is_metric = value[0] == '1';
free(value);
}
}
static void ui_update_frame(UIState *s) {
@@ -598,6 +605,38 @@ static void draw_frame(UIState *s) {
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, &frame_indicies[0]);
}
/*
* Draw a rect at specific position with specific dimensions
*/
static void ui_draw_rounded_rect(
NVGcontext* c,
int x,
int y,
int width,
int height,
int radius,
NVGcolor color
) {
int bottom_x = x + width;
int bottom_y = y + height;
nvgBeginPath(c);
// Position the rect
nvgRoundedRect(c, x, y, bottom_x, bottom_y, radius);
// Color the rect
nvgFillColor(c, color);
// Draw the rect
nvgFill(c);
// Draw white border around rect
nvgStrokeColor(c, nvgRGBA(255,255,255,200));
nvgStroke(c);
}
// Draw all world space objects.
static void ui_draw_world(UIState *s) {
const UIScene *scene = &s->scene;
@@ -605,6 +644,19 @@ static void ui_draw_world(UIState *s) {
return;
}
/******************************************
* Add background rect so it's easier to see in
* light background scenes
******************************************/
// Draw background around speed text
// Left side
ui_draw_rounded_rect(s->vg, -15, 0, 570, 180, 20, nvgRGBA(10,10,10,170));
// Right side
ui_draw_rounded_rect(s->vg, 1920-530, 0, 150, 180, 20, nvgRGBA(10,10,10,170));
/******************************************/
draw_steering(s, scene->v_ego, scene->angle_steers);
// draw paths
@@ -621,13 +673,28 @@ static void ui_draw_world(UIState *s) {
if (scene->lead_status) {
char radar_str[16];
int lead_v_rel = (int)(2.236 * scene->lead_v_rel);
snprintf(radar_str, sizeof(radar_str), "%3d m %+d mph",
(int)(scene->lead_d_rel), lead_v_rel);
/******************************************
* Add background rect so it's easier to see in
* light background scenes
******************************************/
// Draw background for radar text
ui_draw_rounded_rect(s->vg, 578, 0, 195, 180, 20, nvgRGBA(10,10,10,170));
/******************************************/
if (s->is_metric) {
int lead_v_rel = (int)(3.6 * scene->lead_v_rel);
snprintf(radar_str, sizeof(radar_str), "%3d m %+d kph",
(int)(scene->lead_d_rel), lead_v_rel);
} else {
int lead_v_rel = (int)(2.236 * scene->lead_v_rel);
snprintf(radar_str, sizeof(radar_str), "%3d m %+d mph",
(int)(scene->lead_d_rel), lead_v_rel);
}
nvgFontSize(s->vg, 96.0f);
nvgFillColor(s->vg, nvgRGBA(128, 128, 0, 192));
nvgFillColor(s->vg, nvgRGBA(200, 200, 0, 192));
nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_TOP);
nvgText(s->vg, 1920 / 2, 150, radar_str, NULL);
nvgText(s->vg, 1920 / 2 - 20, 40, radar_str, NULL);
// 2.7 m fudge factor
draw_cross(s, scene->lead_d_rel + 2.7, scene->lead_y_rel, 15,
@@ -638,11 +705,10 @@ static void ui_draw_world(UIState *s) {
static void ui_draw_vision(UIState *s) {
const UIScene *scene = &s->scene;
if (scene->engaged) {
glClearColor(1.0, 0.5, 0.0, 1.0);
} else {
glClearColor(0.1, 0.1, 0.1, 1.0);
}
// if (scene->engaged) {
// glClearColor(1.0, 0.5, 0.0, 1.0);
// } else {
glClearColor(0.1, 0.1, 0.1, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
draw_frame(s);
@@ -662,26 +728,57 @@ static void ui_draw_vision(UIState *s) {
// draw speed
char speed_str[16];
nvgFontSize(s->vg, 128.0f);
float defaultfontsize = 128.0f;
float labelfontsize = 65.0f;
if (scene->engaged) {
nvgFillColor(s->vg, nvgRGBA(255, 128, 0, 192));
// Add label
nvgFontSize(s->vg, labelfontsize);
nvgTextAlign(s->vg, NVG_ALIGN_LEFT | NVG_ALIGN_BASELINE);
nvgText(s->vg, 20, 175-30, "OpenPilot: On", NULL);
} else {
nvgFillColor(s->vg, nvgRGBA(64, 64, 64, 192));
nvgFillColor(s->vg, nvgRGBA(195, 195, 195, 192));
// Add label
nvgFontSize(s->vg, labelfontsize);
nvgTextAlign(s->vg, NVG_ALIGN_LEFT | NVG_ALIGN_BASELINE);
nvgText(s->vg, 20, 175-30, "OpenPilot: Off", NULL);
}
nvgFontSize(s->vg, defaultfontsize);
if (scene->v_cruise != 255 && scene->v_cruise != 0) {
// Convert KPH to MPH.
snprintf(speed_str, sizeof(speed_str), "%3d MPH",
(int)(scene->v_cruise * 0.621371 + 0.5));
if (s->is_metric) {
snprintf(speed_str, sizeof(speed_str), "%3d KPH",
(int)(scene->v_cruise + 0.5));
} else {
// Convert KPH to MPH.
snprintf(speed_str, sizeof(speed_str), "%3d MPH",
(int)(scene->v_cruise * 0.621371 + 0.5));
}
nvgTextAlign(s->vg, NVG_ALIGN_RIGHT | NVG_ALIGN_BASELINE);
nvgText(s->vg, 500, 150, speed_str, NULL);
nvgText(s->vg, 480, 95, speed_str, NULL);
}
// Add label
nvgFontSize(s->vg, labelfontsize);
nvgFillColor(s->vg, nvgRGBA(255, 255, 255, 192));
snprintf(speed_str, sizeof(speed_str), "%3d MPH",
(int)(scene->v_ego * 2.237 + 0.5));
nvgTextAlign(s->vg, NVG_ALIGN_LEFT | NVG_ALIGN_BASELINE);
nvgText(s->vg, 1920 - 500, 150, speed_str, NULL);
nvgText(s->vg, 1920 - 475, 175-30, "Current Speed", NULL);
/******************************************/
nvgFontSize(s->vg, defaultfontsize);
nvgFillColor(s->vg, nvgRGBA(255, 255, 255, 192));
if (s->is_metric) {
snprintf(speed_str, sizeof(speed_str), "%3d KPH",
(int)(scene->v_ego * 3.6 + 0.5));
} else {
snprintf(speed_str, sizeof(speed_str), "%3d MPH",
(int)(scene->v_ego * 2.237 + 0.5));
}
nvgTextAlign(s->vg, NVG_ALIGN_LEFT | NVG_ALIGN_BASELINE);
nvgText(s->vg, 1920 - 500, 95, speed_str, NULL);
/*nvgFontSize(s->vg, 64.0f);
nvgTextAlign(s->vg, NVG_ALIGN_RIGHT | NVG_ALIGN_BASELINE);
@@ -697,19 +794,38 @@ static void ui_draw_vision(UIState *s) {
}
}
nvgEndFrame(s->vg);
glDisable(GL_BLEND);
// glDisable(GL_CULL_FACE);
}
static void ui_draw_alerts(UIState *s) {
const UIScene *scene = &s->scene;
// dont draw alerts that are outdated by > 20 secs
if ((nanos_since_boot() - scene->alert_ts) >= 20000000000ULL) {
return;
}
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glClear(GL_STENCIL_BUFFER_BIT);
nvgBeginFrame(s->vg, s->fb_w, s->fb_h, 1.0f);
// draw alert text
if (strlen(scene->alert_text1) > 0) {
nvgBeginPath(s->vg);
nvgRoundedRect(s->vg, 100, 200, 1700, 800, 40);
nvgFillColor(s->vg, nvgRGBA(10, 10, 10, 220));
nvgFill(s->vg);
nvgFontSize(s->vg, 200.0f);
nvgFillColor(s->vg, nvgRGBA(255, 0, 0, 255));
nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_TOP);
nvgTextBox(s->vg, 100 + 50, 200 + 50, 1700 - 50, scene->alert_text1,
NULL);
if (strlen(scene->alert_text2) > 0) {
nvgFillColor(s->vg, nvgRGBA(255, 255, 255, 255));
nvgFontSize(s->vg, 100.0f);
@@ -720,11 +836,10 @@ static void ui_draw_vision(UIState *s) {
nvgEndFrame(s->vg);
glDisable(GL_BLEND);
glDisable(GL_CULL_FACE);
}
static void ui_draw_blank(UIState *s) {
glClearColor(0.1, 0.1, 0.1, 1.0);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
}
@@ -735,6 +850,8 @@ static void ui_draw(UIState *s) {
ui_draw_blank(s);
}
ui_draw_alerts(s);
eglSwapBuffers(s->display, s->surface);
assert(glGetError() == GL_NO_ERROR);
}
@@ -840,19 +957,22 @@ static void ui_update(UIState *s) {
int ret = zmq_poll(polls, num_polls, 0);
if (ret < 0) {
printf("poll failed (%d)\n", ret);
LOGW("poll failed (%d)", ret);
break;
}
if (ret == 0) {
break;
}
// awake on any activity
set_awake(s, true);
if (s->vision_connected && polls[4].revents) {
// vision ipc event
VisionPacket rp;
err = vipc_recv(s->ipc_fd, &rp);
if (err <= 0) {
printf("vision disconnected\n");
LOGW("vision disconnected");
close(s->ipc_fd);
s->ipc_fd = -1;
s->vision_connected = false;
@@ -945,6 +1065,9 @@ static void ui_update(UIState *s) {
s->scene.alert_text2[0] = '\0';
}
s->scene.awareness_status = datad.awarenessStatus;
s->scene.alert_ts = eventd.logMonoTime;
} else if (eventd.which == cereal_Event_live20) {
struct cereal_Live20Data datad;
cereal_read_Live20Data(&datad, eventd.live20);
@@ -1074,12 +1197,23 @@ int main() {
vision_connect_thread, s);
assert(err == 0);
TouchState touch = {0};
touch_init(&touch);
while (!do_exit) {
pthread_mutex_lock(&s->lock);
ui_update(s);
if (s->awake) {
pthread_mutex_lock(&s->lock);
ui_update(s);
ui_draw(s);
pthread_mutex_unlock(&s->lock);
}
// awake on any touch
int touch_x = -1, touch_y = -1;
int touched = touch_poll(&touch, &touch_x, &touch_y);
if (touched == 1) {
// touch event will still happen :(
set_awake(s, true);
}
// manage wakefulness
@@ -1089,22 +1223,14 @@ int main() {
set_awake(s, false);
}
// always awake if vision is connected
if (s->vision_connected) {
set_awake(s, true);
} else {
int touch_x = -1, touch_y = -1;
err = touch_poll(&s->touch, &touch_x, &touch_y);
if (err == 1) {
// touch event will still happen :(
set_awake(s, true);
}
}
pthread_mutex_unlock(&s->lock);
// no simple way to do 30fps vsync with surfaceflinger...
usleep(30000);
}
set_awake(s, true);
err = pthread_join(connect_thread_handle, NULL);
assert(err == 0);

Binary file not shown.