Skip to content

Commit 683b615

Browse files
author
Vehicle Researcher
committed
Squashed 'opendbc/' changes from c0eba09..4f82d01
4f82d01 gitignore 5cb8345 Honda FCM: diagnostic signals d309cdc Added linter to opendbc (#203) d452706 add requirements.txt ec3b459 deterministic dependency order a265d35 Azure pipelines ci (#202) bce9a2e packer depends on libdbc 5d5fdd6 no more python version of libdbc, everything through cython 541705b move CANDefine to parser code da25c52 add test for can define 0ba7926 unify can packer and parser 25d8800 consistent naming a5c640a fix linter be210fe remove obsolete make file ffd9dca opendbc needs cereal b559f63 remove more make d092949 seems to work now 41e8083 don't make 3254d1f think scons works eb78f6a scons sort of working 0ef1e35 fix gitignore e155e01 Can migration (#199) 3eded83 Honda: correct steering torque sensor sign to be consistent with standard convention (left+) 32f70e2 Fix outback endianness consistency (#196) a7da471 Update subaru_outback_2015_eyesight.dbc (#195) git-subtree-dir: opendbc git-subtree-split: 4f82d01
1 parent 67c4121 commit 683b615

File tree

63 files changed

+2721
-215
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+2721
-215
lines changed

.gitignore

+8
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,10 @@
11
*.pyc
2+
*.os
3+
*.tmp
24
.*.swp
5+
can/*.so
6+
can/build/
7+
can/obj/
8+
can/packer_pyx.cpp
9+
can/parser_pyx.cpp
10+
can/packer_impl.cpp

Dockerfile

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from ubuntu:16.04
2+
3+
RUN apt-get update && apt-get install -y libzmq3-dev clang wget git autoconf libtool curl make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev llvm libncurses5-dev libncursesw5-dev xz-utils tk-dev libffi-dev liblzma-dev python-openssl
4+
5+
RUN curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash
6+
ENV PATH="/root/.pyenv/bin:/root/.pyenv/shims:${PATH}"
7+
RUN pyenv install 3.7.3
8+
RUN pyenv global 3.7.3
9+
RUN pyenv rehash
10+
11+
COPY requirements.txt /tmp/
12+
RUN pip install -r /tmp/requirements.txt
13+
14+
ENV PYTHONPATH=/project
15+
16+
# TODO: Add tag to cereal
17+
RUN git clone https://github.com/commaai/cereal.git /project/cereal
18+
RUN /project/cereal/install_capnp.sh
19+
20+
WORKDIR /project
21+
22+
COPY SConstruct .
23+
COPY . /project/opendbc
24+
25+
RUN scons -c && scons -j$(nproc)

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ For example:
4242
SG_ VEHICLE_SPEED : 7|15@0+ (0.01,0) [0|250] "kph" PCM
4343
```
4444
45-
- Signal's size: always use the smallest amount of bits possible. For example, let's say I'm reverse engineering the gas pedal position and I've determined that it's in a 3 bytes message. For 0% pedal position I read a message value of `0x00 0x00 0x00`, while for 100% of pedal position I read `0x64 0x00 0x00`: clearly, the gas pedal position is within the first byte of the message and I might be tempted to define the signal `GAS_POS` as:
45+
- Signal size: always use the smallest amount of bits possible. For example, let's say I'm reverse engineering the gas pedal position and I've determined that it's in a 3 bytes message. For 0% pedal position I read a message value of `0x00 0x00 0x00`, while for 100% of pedal position I read `0x64 0x00 0x00`: clearly, the gas pedal position is within the first byte of the message and I might be tempted to define the signal `GAS_POS` as:
4646
```
4747
SG_ GAS_POS : 7|8@0+ (1,0) [0|100] "%" PCM
4848
```

SConstruct

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import os
2+
import subprocess
3+
4+
zmq = 'zmq'
5+
arch = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip()
6+
7+
cereal_dir = Dir('.')
8+
9+
cpppath = [
10+
'#',
11+
'#cereal',
12+
"#cereal/messaging",
13+
"#opendbc/can",
14+
'/usr/lib/include',
15+
]
16+
17+
AddOption('--test',
18+
action='store_true',
19+
help='build test files')
20+
21+
AddOption('--asan',
22+
action='store_true',
23+
help='turn on ASAN')
24+
25+
ccflags_asan = ["-fsanitize=address", "-fno-omit-frame-pointer"] if GetOption('asan') else []
26+
ldflags_asan = ["-fsanitize=address"] if GetOption('asan') else []
27+
28+
env = Environment(
29+
ENV=os.environ,
30+
CC='clang',
31+
CXX='clang++',
32+
CCFLAGS=[
33+
"-g",
34+
"-fPIC",
35+
"-O2",
36+
"-Werror=implicit-function-declaration",
37+
"-Werror=incompatible-pointer-types",
38+
"-Werror=int-conversion",
39+
"-Werror=return-type",
40+
"-Werror=format-extra-args",
41+
] + ccflags_asan,
42+
LDFLAGS=ldflags_asan,
43+
LINKFLAGS=ldflags_asan,
44+
45+
CFLAGS="-std=gnu11",
46+
CXXFLAGS="-std=c++14",
47+
CPPPATH=cpppath,
48+
)
49+
50+
Export('env', 'zmq', 'arch')
51+
52+
cereal = [File('#cereal/libcereal.a')]
53+
messaging = [File('#cereal/libmessaging.a')]
54+
Export('cereal', 'messaging')
55+
56+
SConscript(['cereal/SConscript'])
57+
SConscript(['opendbc/can/SConscript'])

acura_ilx_2016_can_generated.dbc

+2-2
Original file line numberDiff line numberDiff line change
@@ -271,8 +271,8 @@ BO_ 342 STEERING_SENSORS: 6 EPS
271271
SG_ CHECKSUM : 43|4@0+ (1,0) [0|3] "" EON
272272

273273
BO_ 399 STEER_STATUS: 7 EPS
274-
SG_ STEER_TORQUE_SENSOR : 7|16@0- (1,0) [-31000|31000] "tbd" EON
275-
SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON
274+
SG_ STEER_TORQUE_SENSOR : 7|16@0- (-1,0) [-31000|31000] "tbd" EON
275+
SG_ STEER_TORQUE_MOTOR : 23|16@0- (-1,0) [-31000|31000] "tbd" EON
276276
SG_ STEER_STATUS : 39|4@0+ (1,0) [0|15] "" EON
277277
SG_ STEER_CONTROL_ACTIVE : 35|1@0+ (1,0) [0|1] "" EON
278278
SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON

acura_rdx_2018_can_generated.dbc

+2-2
Original file line numberDiff line numberDiff line change
@@ -259,8 +259,8 @@ BO_ 392 GEARBOX: 6 XXX
259259
SG_ GEAR : 36|5@0+ (1,0) [0|31] "" EON
260260

261261
BO_ 399 STEER_STATUS: 6 EPS
262-
SG_ STEER_TORQUE_SENSOR : 7|12@0- (1,0) [-2047.5|2047.5] "tbd" EON
263-
SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON
262+
SG_ STEER_TORQUE_SENSOR : 7|12@0- (-1,0) [-2047.5|2047.5] "tbd" EON
263+
SG_ STEER_TORQUE_MOTOR : 23|16@0- (-1,0) [-31000|31000] "tbd" EON
264264
SG_ STEER_STATUS : 35|4@0+ (1,0) [0|15] "" EON
265265
SG_ STEER_CONTROL_ACTIVE : 36|1@0+ (1,0) [0|1] "" EON
266266
SG_ COUNTER : 45|2@0+ (1,0) [0|3] "" EON

azure-pipelines.yml

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
pr: none
2+
3+
pool:
4+
vmImage: 'ubuntu-16.04'
5+
steps:
6+
- script: |
7+
set -e
8+
docker build -t opendbc .
9+
displayName: 'Build'
10+
- script: |
11+
docker run opendbc bash -c "python -m unittest discover opendbc"
12+
displayName: 'Unit tests'
13+
- script: |
14+
docker run opendbc bash -c "cd opendbc/can/tests/linter_python; PYTHONPATH=/ ./flake8_opendbc.sh"
15+
docker run opendbc bash -c "cd opendbc/can/tests/linter_python; PYTHONPATH=/ ./pylint_opendbc.sh"
16+
displayName: 'Python linter'

can/SConscript

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
Import('env', 'cereal')
2+
3+
import os
4+
from opendbc.can.process_dbc import process
5+
6+
dbcs = []
7+
for x in sorted(os.listdir('../')):
8+
if x.endswith(".dbc"):
9+
def compile_dbc(target, source, env):
10+
process(source[0].path, target[0].path)
11+
in_fn = [os.path.join('../', x), 'dbc_template.cc']
12+
out_fn = os.path.join('dbc_out', x.replace(".dbc", ".cc"))
13+
dbc = env.Command(out_fn, in_fn, compile_dbc)
14+
dbcs.append(dbc)
15+
16+
17+
libdbc = env.SharedLibrary('libdbc', ["dbc.cc", "parser.cc", "packer.cc", "common.cc"]+dbcs, LIBS=["capnp", "kj"])
18+
19+
# packer
20+
env.Command(['packer_pyx.so'],
21+
[libdbc, 'packer_pyx.pyx', 'packer_pyx_setup.py'],
22+
"cd opendbc/can && python3 packer_pyx_setup.py build_ext --inplace")
23+
24+
# parser
25+
env.Command(['parser_pyx.so'],
26+
[libdbc, cereal, 'parser_pyx_setup.py', 'parser_pyx.pyx', 'common.pxd'],
27+
"cd opendbc/can && python3 parser_pyx_setup.py build_ext --inplace")

can/__init__.py

Whitespace-only changes.

can/can_define.py

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from opendbc.can.parser_pyx import CANDefine # pylint: disable=no-name-in-module, import-error
2+
assert CANDefine

can/common.cc

+165
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
#include "common.h"
2+
3+
unsigned int honda_checksum(unsigned int address, uint64_t d, int l) {
4+
d >>= ((8-l)*8); // remove padding
5+
d >>= 4; // remove checksum
6+
7+
int s = 0;
8+
while (address) { s += (address & 0xF); address >>= 4; }
9+
while (d) { s += (d & 0xF); d >>= 4; }
10+
s = 8-s;
11+
s &= 0xF;
12+
13+
return s;
14+
}
15+
16+
unsigned int toyota_checksum(unsigned int address, uint64_t d, int l) {
17+
d >>= ((8-l)*8); // remove padding
18+
d >>= 8; // remove checksum
19+
20+
unsigned int s = l;
21+
while (address) { s += address & 0xff; address >>= 8; }
22+
while (d) { s += d & 0xff; d >>= 8; }
23+
24+
return s & 0xFF;
25+
}
26+
27+
// Static lookup table for fast computation of CRC8 poly 0x2F, aka 8H2F/AUTOSAR
28+
uint8_t crc8_lut_8h2f[256];
29+
30+
void gen_crc_lookup_table(uint8_t poly, uint8_t crc_lut[]) {
31+
uint8_t crc;
32+
int i, j;
33+
34+
for (i = 0; i < 256; i++) {
35+
crc = i;
36+
for (j = 0; j < 8; j++) {
37+
if ((crc & 0x80) != 0)
38+
crc = (uint8_t)((crc << 1) ^ poly);
39+
else
40+
crc <<= 1;
41+
}
42+
crc_lut[i] = crc;
43+
}
44+
}
45+
46+
void init_crc_lookup_tables() {
47+
// At init time, set up static lookup tables for fast CRC computation.
48+
49+
gen_crc_lookup_table(0x2F, crc8_lut_8h2f); // CRC-8 8H2F/AUTOSAR for Volkswagen
50+
}
51+
52+
unsigned int volkswagen_crc(unsigned int address, uint64_t d, int l) {
53+
// Volkswagen uses standard CRC8 8H2F/AUTOSAR, but they compute it with
54+
// a magic variable padding byte tacked onto the end of the payload.
55+
// https://www.autosar.org/fileadmin/user_upload/standards/classic/4-3/AUTOSAR_SWS_CRCLibrary.pdf
56+
57+
uint8_t *dat = (uint8_t *)&d;
58+
uint8_t crc = 0xFF; // Standard init value for CRC8 8H2F/AUTOSAR
59+
60+
// CRC the payload first, skipping over the first byte where the CRC lives.
61+
for (int i = 1; i < l; i++) {
62+
crc ^= dat[i];
63+
crc = crc8_lut_8h2f[crc];
64+
}
65+
66+
// Look up and apply the magic final CRC padding byte, which permutes by CAN
67+
// address, and additionally (for SOME addresses) by the message counter.
68+
uint8_t counter = dat[1] & 0x0F;
69+
switch(address) {
70+
case 0x86: // LWI_01 Steering Angle
71+
crc ^= (uint8_t[]){0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86}[counter];
72+
break;
73+
case 0x9F: // EPS_01 Electric Power Steering
74+
crc ^= (uint8_t[]){0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5}[counter];
75+
break;
76+
case 0xAD: // Getriebe_11 Automatic Gearbox
77+
crc ^= (uint8_t[]){0x3F,0x69,0x39,0xDC,0x94,0xF9,0x14,0x64,0xD8,0x6A,0x34,0xCE,0xA2,0x55,0xB5,0x2C}[counter];
78+
break;
79+
case 0xFD: // ESP_21 Electronic Stability Program
80+
crc ^= (uint8_t[]){0xB4,0xEF,0xF8,0x49,0x1E,0xE5,0xC2,0xC0,0x97,0x19,0x3C,0xC9,0xF1,0x98,0xD6,0x61}[counter];
81+
break;
82+
case 0x106: // ESP_05 Electronic Stability Program
83+
crc ^= (uint8_t[]){0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07}[counter];
84+
break;
85+
case 0x117: // ACC_10 Automatic Cruise Control
86+
crc ^= (uint8_t[]){0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC}[counter];
87+
break;
88+
case 0x122: // ACC_06 Automatic Cruise Control
89+
crc ^= (uint8_t[]){0x37,0x7D,0xF3,0xA9,0x18,0x46,0x6D,0x4D,0x3D,0x71,0x92,0x9C,0xE5,0x32,0x10,0xB9}[counter];
90+
break;
91+
case 0x126: // HCA_01 Heading Control Assist
92+
crc ^= (uint8_t[]){0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA}[counter];
93+
break;
94+
case 0x12B: // GRA_ACC_01 Steering wheel controls for ACC
95+
crc ^= (uint8_t[]){0x6A,0x38,0xB4,0x27,0x22,0xEF,0xE1,0xBB,0xF8,0x80,0x84,0x49,0xC7,0x9E,0x1E,0x2B}[counter];
96+
break;
97+
case 0x187: // EV_Gearshift "Gear" selection data for EVs with no gearbox
98+
crc ^= (uint8_t[]){0x7F,0xED,0x17,0xC2,0x7C,0xEB,0x44,0x21,0x01,0xFA,0xDB,0x15,0x4A,0x6B,0x23,0x05}[counter];
99+
break;
100+
case 0x30C: // ACC_02 Automatic Cruise Control
101+
crc ^= (uint8_t[]){0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F}[counter];
102+
break;
103+
case 0x3C0: // Klemmen_Status_01 ignition and starting status
104+
crc ^= (uint8_t[]){0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3}[counter];
105+
break;
106+
case 0x65D: // ESP_20 Electronic Stability Program
107+
crc ^= (uint8_t[]){0xAC,0xB3,0xAB,0xEB,0x7A,0xE1,0x3B,0xF7,0x73,0xBA,0x7C,0x9E,0x06,0x5F,0x02,0xD9}[counter];
108+
break;
109+
default: // As-yet undefined CAN message, CRC check expected to fail
110+
printf("Attempt to CRC check undefined Volkswagen message 0x%02X\n", address);
111+
crc ^= (uint8_t[]){0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}[counter];
112+
break;
113+
}
114+
crc = crc8_lut_8h2f[crc];
115+
116+
return crc ^ 0xFF; // Return after standard final XOR for CRC8 8H2F/AUTOSAR
117+
}
118+
119+
120+
unsigned int pedal_checksum(uint64_t d, int l) {
121+
uint8_t crc = 0xFF;
122+
uint8_t poly = 0xD5; // standard crc8
123+
124+
d >>= ((8-l)*8); // remove padding
125+
d >>= 8; // remove checksum
126+
127+
uint8_t *dat = (uint8_t *)&d;
128+
129+
int i, j;
130+
for (i = 0; i < l - 1; i++) {
131+
crc ^= dat[i];
132+
for (j = 0; j < 8; j++) {
133+
if ((crc & 0x80) != 0) {
134+
crc = (uint8_t)((crc << 1) ^ poly);
135+
}
136+
else {
137+
crc <<= 1;
138+
}
139+
}
140+
}
141+
return crc;
142+
}
143+
144+
145+
uint64_t read_u64_be(const uint8_t* v) {
146+
return (((uint64_t)v[0] << 56)
147+
| ((uint64_t)v[1] << 48)
148+
| ((uint64_t)v[2] << 40)
149+
| ((uint64_t)v[3] << 32)
150+
| ((uint64_t)v[4] << 24)
151+
| ((uint64_t)v[5] << 16)
152+
| ((uint64_t)v[6] << 8)
153+
| (uint64_t)v[7]);
154+
}
155+
156+
uint64_t read_u64_le(const uint8_t* v) {
157+
return ((uint64_t)v[0]
158+
| ((uint64_t)v[1] << 8)
159+
| ((uint64_t)v[2] << 16)
160+
| ((uint64_t)v[3] << 24)
161+
| ((uint64_t)v[4] << 32)
162+
| ((uint64_t)v[5] << 40)
163+
| ((uint64_t)v[6] << 48)
164+
| ((uint64_t)v[7] << 56));
165+
}

0 commit comments

Comments
 (0)