From 683b6151ce59def5c299fa4b9ba5f70b14b85cb7 Mon Sep 17 00:00:00 2001 From: Vehicle Researcher Date: Fri, 13 Dec 2019 13:02:48 -0800 Subject: [PATCH] Squashed 'opendbc/' changes from c0eba096..4f82d01e 4f82d01e gitignore 5cb83454 Honda FCM: diagnostic signals d309cdce Added linter to opendbc (#203) d452706f add requirements.txt ec3b4595 deterministic dependency order a265d351 Azure pipelines ci (#202) bce9a2e1 packer depends on libdbc 5d5fdd6a no more python version of libdbc, everything through cython 541705bf move CANDefine to parser code da25c52a add test for can define 0ba7926b unify can packer and parser 25d88009 consistent naming a5c640a5 fix linter be210fef remove obsolete make file ffd9dca7 opendbc needs cereal b559f63d remove more make d0929496 seems to work now 41e80836 don't make 3254d1fc think scons works eb78f6aa scons sort of working 0ef1e35d fix gitignore e155e017 Can migration (#199) 3eded83a Honda: correct steering torque sensor sign to be consistent with standard convention (left+) 32f70e2f Fix outback endianness consistency (#196) a7da471f Update subaru_outback_2015_eyesight.dbc (#195) git-subtree-dir: opendbc git-subtree-split: 4f82d01ebc78109888954d9807d320e3c27896fd --- .gitignore | 8 + Dockerfile | 25 + README.md | 2 +- SConstruct | 57 ++ acura_ilx_2016_can_generated.dbc | 4 +- acura_rdx_2018_can_generated.dbc | 4 +- azure-pipelines.yml | 16 + can/SConscript | 27 + can/__init__.py | 0 can/can_define.py | 2 + can/common.cc | 165 +++++ can/common.h | 70 +++ can/common.pxd | 82 +++ can/common_dbc.h | 82 +++ can/dbc.cc | 31 + can/dbc.py | 275 ++++++++ can/dbc_out/.gitignore | 2 + can/dbc_out/.gitkeep | 0 can/dbc_template.cc | 81 +++ can/packer.cc | 108 ++++ can/packer.py | 3 + can/packer_pyx.pyx | 67 ++ can/packer_pyx_setup.py | 60 ++ can/parser.cc | 239 +++++++ can/parser.py | 2 + can/parser_pyx.pyx | 188 ++++++ can/parser_pyx_setup.py | 59 ++ can/process_dbc.py | 112 ++++ can/tests/.gitignore | 1 + can/tests/__init__.py | 0 can/tests/linter_python/.pylintrc | 585 ++++++++++++++++++ can/tests/linter_python/flake8_opendbc.sh | 8 + can/tests/linter_python/pylint_opendbc.sh | 11 + can/tests/test_define.py | 27 + can/tests/test_packer_parser.py | 105 ++++ generator/honda/_bosch_2018.dbc | 4 +- generator/honda/acura_ilx_2016_can.dbc | 4 +- generator/honda/acura_rdx_2018_can.dbc | 4 +- .../honda/honda_civic_touring_2016_can.dbc | 4 +- .../honda/honda_crv_touring_2016_can.dbc | 4 +- generator/honda/honda_fit_ex_2018_can.dbc | 4 +- generator/honda/honda_fit_hybrid_2018_can.dbc | 4 +- generator/honda/honda_odyssey_exl_2018.dbc | 4 +- ...odyssey_extreme_edition_2018_china_can.dbc | 4 +- .../honda/honda_pilot_touring_2017_can.dbc | 4 +- ...honda_ridgeline_black_edition_2017_can.dbc | 4 +- honda_accord_lx15t_2018_can_generated.dbc | 4 +- honda_accord_s2t_2018_can_generated.dbc | 4 +- ..._civic_hatchback_ex_2017_can_generated.dbc | 4 +- honda_civic_touring_2016_can_generated.dbc | 12 +- honda_clarity_hybrid_2018_can.dbc | 4 +- honda_crv_ex_2017_can_generated.dbc | 4 +- honda_crv_hybrid_2019_can_generated.dbc | 4 +- honda_crv_touring_2016_can_generated.dbc | 4 +- honda_fit_ex_2018_can_generated.dbc | 4 +- honda_fit_hybrid_2018_can_generated.dbc | 4 +- honda_insight_ex_2019_can_generated.dbc | 4 +- honda_odyssey_exl_2018_generated.dbc | 4 +- ...treme_edition_2018_china_can_generated.dbc | 4 +- honda_pilot_touring_2017_can_generated.dbc | 4 +- ...eline_black_edition_2017_can_generated.dbc | 4 +- requirements.txt | 7 + subaru_outback_2015_eyesight.dbc | 309 +++++---- 63 files changed, 2721 insertions(+), 215 deletions(-) create mode 100644 Dockerfile create mode 100644 SConstruct create mode 100644 azure-pipelines.yml create mode 100644 can/SConscript create mode 100644 can/__init__.py create mode 100644 can/can_define.py create mode 100644 can/common.cc create mode 100644 can/common.h create mode 100644 can/common.pxd create mode 100644 can/common_dbc.h create mode 100644 can/dbc.cc create mode 100755 can/dbc.py create mode 100644 can/dbc_out/.gitignore create mode 100644 can/dbc_out/.gitkeep create mode 100644 can/dbc_template.cc create mode 100644 can/packer.cc create mode 100644 can/packer.py create mode 100644 can/packer_pyx.pyx create mode 100644 can/packer_pyx_setup.py create mode 100644 can/parser.cc create mode 100644 can/parser.py create mode 100644 can/parser_pyx.pyx create mode 100644 can/parser_pyx_setup.py create mode 100755 can/process_dbc.py create mode 100644 can/tests/.gitignore create mode 100644 can/tests/__init__.py create mode 100644 can/tests/linter_python/.pylintrc create mode 100755 can/tests/linter_python/flake8_opendbc.sh create mode 100755 can/tests/linter_python/pylint_opendbc.sh create mode 100644 can/tests/test_define.py create mode 100644 can/tests/test_packer_parser.py create mode 100644 requirements.txt diff --git a/.gitignore b/.gitignore index d18402de39..5eb52dcca3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,10 @@ *.pyc +*.os +*.tmp .*.swp +can/*.so +can/build/ +can/obj/ +can/packer_pyx.cpp +can/parser_pyx.cpp +can/packer_impl.cpp diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000..e105313756 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,25 @@ +from ubuntu:16.04 + +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 + +RUN curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash +ENV PATH="/root/.pyenv/bin:/root/.pyenv/shims:${PATH}" +RUN pyenv install 3.7.3 +RUN pyenv global 3.7.3 +RUN pyenv rehash + +COPY requirements.txt /tmp/ +RUN pip install -r /tmp/requirements.txt + +ENV PYTHONPATH=/project + +# TODO: Add tag to cereal +RUN git clone https://github.com/commaai/cereal.git /project/cereal +RUN /project/cereal/install_capnp.sh + +WORKDIR /project + +COPY SConstruct . +COPY . /project/opendbc + +RUN scons -c && scons -j$(nproc) diff --git a/README.md b/README.md index eec42dfefa..c11cf3fdcf 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ For example: SG_ VEHICLE_SPEED : 7|15@0+ (0.01,0) [0|250] "kph" PCM ``` -- 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: +- 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: ``` SG_ GAS_POS : 7|8@0+ (1,0) [0|100] "%" PCM ``` diff --git a/SConstruct b/SConstruct new file mode 100644 index 0000000000..b051d182e1 --- /dev/null +++ b/SConstruct @@ -0,0 +1,57 @@ +import os +import subprocess + +zmq = 'zmq' +arch = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip() + +cereal_dir = Dir('.') + +cpppath = [ + '#', + '#cereal', + "#cereal/messaging", + "#opendbc/can", + '/usr/lib/include', +] + +AddOption('--test', + action='store_true', + help='build test files') + +AddOption('--asan', + action='store_true', + help='turn on ASAN') + +ccflags_asan = ["-fsanitize=address", "-fno-omit-frame-pointer"] if GetOption('asan') else [] +ldflags_asan = ["-fsanitize=address"] if GetOption('asan') else [] + +env = Environment( + ENV=os.environ, + CC='clang', + CXX='clang++', + CCFLAGS=[ + "-g", + "-fPIC", + "-O2", + "-Werror=implicit-function-declaration", + "-Werror=incompatible-pointer-types", + "-Werror=int-conversion", + "-Werror=return-type", + "-Werror=format-extra-args", + ] + ccflags_asan, + LDFLAGS=ldflags_asan, + LINKFLAGS=ldflags_asan, + + CFLAGS="-std=gnu11", + CXXFLAGS="-std=c++14", + CPPPATH=cpppath, +) + +Export('env', 'zmq', 'arch') + +cereal = [File('#cereal/libcereal.a')] +messaging = [File('#cereal/libmessaging.a')] +Export('cereal', 'messaging') + +SConscript(['cereal/SConscript']) +SConscript(['opendbc/can/SConscript']) diff --git a/acura_ilx_2016_can_generated.dbc b/acura_ilx_2016_can_generated.dbc index 2a2a941a59..76444138d3 100644 --- a/acura_ilx_2016_can_generated.dbc +++ b/acura_ilx_2016_can_generated.dbc @@ -271,8 +271,8 @@ BO_ 342 STEERING_SENSORS: 6 EPS SG_ CHECKSUM : 43|4@0+ (1,0) [0|3] "" EON BO_ 399 STEER_STATUS: 7 EPS - SG_ STEER_TORQUE_SENSOR : 7|16@0- (1,0) [-31000|31000] "tbd" EON - SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_SENSOR : 7|16@0- (-1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_MOTOR : 23|16@0- (-1,0) [-31000|31000] "tbd" EON SG_ STEER_STATUS : 39|4@0+ (1,0) [0|15] "" EON SG_ STEER_CONTROL_ACTIVE : 35|1@0+ (1,0) [0|1] "" EON SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON diff --git a/acura_rdx_2018_can_generated.dbc b/acura_rdx_2018_can_generated.dbc index 48c9b3967d..233ece8ffc 100644 --- a/acura_rdx_2018_can_generated.dbc +++ b/acura_rdx_2018_can_generated.dbc @@ -259,8 +259,8 @@ BO_ 392 GEARBOX: 6 XXX SG_ GEAR : 36|5@0+ (1,0) [0|31] "" EON BO_ 399 STEER_STATUS: 6 EPS - SG_ STEER_TORQUE_SENSOR : 7|12@0- (1,0) [-2047.5|2047.5] "tbd" EON - SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_SENSOR : 7|12@0- (-1,0) [-2047.5|2047.5] "tbd" EON + SG_ STEER_TORQUE_MOTOR : 23|16@0- (-1,0) [-31000|31000] "tbd" EON SG_ STEER_STATUS : 35|4@0+ (1,0) [0|15] "" EON SG_ STEER_CONTROL_ACTIVE : 36|1@0+ (1,0) [0|1] "" EON SG_ COUNTER : 45|2@0+ (1,0) [0|3] "" EON diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 0000000000..3841610a6a --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,16 @@ +pr: none + +pool: + vmImage: 'ubuntu-16.04' +steps: +- script: | + set -e + docker build -t opendbc . + displayName: 'Build' +- script: | + docker run opendbc bash -c "python -m unittest discover opendbc" + displayName: 'Unit tests' +- script: | + docker run opendbc bash -c "cd opendbc/can/tests/linter_python; PYTHONPATH=/ ./flake8_opendbc.sh" + docker run opendbc bash -c "cd opendbc/can/tests/linter_python; PYTHONPATH=/ ./pylint_opendbc.sh" + displayName: 'Python linter' diff --git a/can/SConscript b/can/SConscript new file mode 100644 index 0000000000..94a45ea185 --- /dev/null +++ b/can/SConscript @@ -0,0 +1,27 @@ +Import('env', 'cereal') + +import os +from opendbc.can.process_dbc import process + +dbcs = [] +for x in sorted(os.listdir('../')): + if x.endswith(".dbc"): + def compile_dbc(target, source, env): + process(source[0].path, target[0].path) + in_fn = [os.path.join('../', x), 'dbc_template.cc'] + out_fn = os.path.join('dbc_out', x.replace(".dbc", ".cc")) + dbc = env.Command(out_fn, in_fn, compile_dbc) + dbcs.append(dbc) + + +libdbc = env.SharedLibrary('libdbc', ["dbc.cc", "parser.cc", "packer.cc", "common.cc"]+dbcs, LIBS=["capnp", "kj"]) + +# packer +env.Command(['packer_pyx.so'], + [libdbc, 'packer_pyx.pyx', 'packer_pyx_setup.py'], + "cd opendbc/can && python3 packer_pyx_setup.py build_ext --inplace") + +# parser +env.Command(['parser_pyx.so'], + [libdbc, cereal, 'parser_pyx_setup.py', 'parser_pyx.pyx', 'common.pxd'], + "cd opendbc/can && python3 parser_pyx_setup.py build_ext --inplace") diff --git a/can/__init__.py b/can/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/can/can_define.py b/can/can_define.py new file mode 100644 index 0000000000..12c2d58b20 --- /dev/null +++ b/can/can_define.py @@ -0,0 +1,2 @@ +from opendbc.can.parser_pyx import CANDefine # pylint: disable=no-name-in-module, import-error +assert CANDefine diff --git a/can/common.cc b/can/common.cc new file mode 100644 index 0000000000..5a131eb6c7 --- /dev/null +++ b/can/common.cc @@ -0,0 +1,165 @@ +#include "common.h" + +unsigned int honda_checksum(unsigned int address, uint64_t d, int l) { + d >>= ((8-l)*8); // remove padding + d >>= 4; // remove checksum + + int s = 0; + while (address) { s += (address & 0xF); address >>= 4; } + while (d) { s += (d & 0xF); d >>= 4; } + s = 8-s; + s &= 0xF; + + return s; +} + +unsigned int toyota_checksum(unsigned int address, uint64_t d, int l) { + d >>= ((8-l)*8); // remove padding + d >>= 8; // remove checksum + + unsigned int s = l; + while (address) { s += address & 0xff; address >>= 8; } + while (d) { s += d & 0xff; d >>= 8; } + + return s & 0xFF; +} + +// Static lookup table for fast computation of CRC8 poly 0x2F, aka 8H2F/AUTOSAR +uint8_t crc8_lut_8h2f[256]; + +void gen_crc_lookup_table(uint8_t poly, uint8_t crc_lut[]) { + uint8_t crc; + int i, j; + + for (i = 0; i < 256; i++) { + crc = i; + for (j = 0; j < 8; j++) { + if ((crc & 0x80) != 0) + crc = (uint8_t)((crc << 1) ^ poly); + else + crc <<= 1; + } + crc_lut[i] = crc; + } +} + +void init_crc_lookup_tables() { + // At init time, set up static lookup tables for fast CRC computation. + + gen_crc_lookup_table(0x2F, crc8_lut_8h2f); // CRC-8 8H2F/AUTOSAR for Volkswagen +} + +unsigned int volkswagen_crc(unsigned int address, uint64_t d, int l) { + // Volkswagen uses standard CRC8 8H2F/AUTOSAR, but they compute it with + // a magic variable padding byte tacked onto the end of the payload. + // https://www.autosar.org/fileadmin/user_upload/standards/classic/4-3/AUTOSAR_SWS_CRCLibrary.pdf + + uint8_t *dat = (uint8_t *)&d; + uint8_t crc = 0xFF; // Standard init value for CRC8 8H2F/AUTOSAR + + // CRC the payload first, skipping over the first byte where the CRC lives. + for (int i = 1; i < l; i++) { + crc ^= dat[i]; + crc = crc8_lut_8h2f[crc]; + } + + // Look up and apply the magic final CRC padding byte, which permutes by CAN + // address, and additionally (for SOME addresses) by the message counter. + uint8_t counter = dat[1] & 0x0F; + switch(address) { + case 0x86: // LWI_01 Steering Angle + crc ^= (uint8_t[]){0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86}[counter]; + break; + case 0x9F: // EPS_01 Electric Power Steering + crc ^= (uint8_t[]){0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5,0xF5}[counter]; + break; + case 0xAD: // Getriebe_11 Automatic Gearbox + crc ^= (uint8_t[]){0x3F,0x69,0x39,0xDC,0x94,0xF9,0x14,0x64,0xD8,0x6A,0x34,0xCE,0xA2,0x55,0xB5,0x2C}[counter]; + break; + case 0xFD: // ESP_21 Electronic Stability Program + crc ^= (uint8_t[]){0xB4,0xEF,0xF8,0x49,0x1E,0xE5,0xC2,0xC0,0x97,0x19,0x3C,0xC9,0xF1,0x98,0xD6,0x61}[counter]; + break; + case 0x106: // ESP_05 Electronic Stability Program + crc ^= (uint8_t[]){0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07}[counter]; + break; + case 0x117: // ACC_10 Automatic Cruise Control + crc ^= (uint8_t[]){0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC,0xAC}[counter]; + break; + case 0x122: // ACC_06 Automatic Cruise Control + crc ^= (uint8_t[]){0x37,0x7D,0xF3,0xA9,0x18,0x46,0x6D,0x4D,0x3D,0x71,0x92,0x9C,0xE5,0x32,0x10,0xB9}[counter]; + break; + case 0x126: // HCA_01 Heading Control Assist + crc ^= (uint8_t[]){0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA,0xDA}[counter]; + break; + case 0x12B: // GRA_ACC_01 Steering wheel controls for ACC + crc ^= (uint8_t[]){0x6A,0x38,0xB4,0x27,0x22,0xEF,0xE1,0xBB,0xF8,0x80,0x84,0x49,0xC7,0x9E,0x1E,0x2B}[counter]; + break; + case 0x187: // EV_Gearshift "Gear" selection data for EVs with no gearbox + crc ^= (uint8_t[]){0x7F,0xED,0x17,0xC2,0x7C,0xEB,0x44,0x21,0x01,0xFA,0xDB,0x15,0x4A,0x6B,0x23,0x05}[counter]; + break; + case 0x30C: // ACC_02 Automatic Cruise Control + crc ^= (uint8_t[]){0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F}[counter]; + break; + case 0x3C0: // Klemmen_Status_01 ignition and starting status + crc ^= (uint8_t[]){0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3}[counter]; + break; + case 0x65D: // ESP_20 Electronic Stability Program + crc ^= (uint8_t[]){0xAC,0xB3,0xAB,0xEB,0x7A,0xE1,0x3B,0xF7,0x73,0xBA,0x7C,0x9E,0x06,0x5F,0x02,0xD9}[counter]; + break; + default: // As-yet undefined CAN message, CRC check expected to fail + printf("Attempt to CRC check undefined Volkswagen message 0x%02X\n", address); + crc ^= (uint8_t[]){0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}[counter]; + break; + } + crc = crc8_lut_8h2f[crc]; + + return crc ^ 0xFF; // Return after standard final XOR for CRC8 8H2F/AUTOSAR +} + + +unsigned int pedal_checksum(uint64_t d, int l) { + uint8_t crc = 0xFF; + uint8_t poly = 0xD5; // standard crc8 + + d >>= ((8-l)*8); // remove padding + d >>= 8; // remove checksum + + uint8_t *dat = (uint8_t *)&d; + + int i, j; + for (i = 0; i < l - 1; i++) { + crc ^= dat[i]; + for (j = 0; j < 8; j++) { + if ((crc & 0x80) != 0) { + crc = (uint8_t)((crc << 1) ^ poly); + } + else { + crc <<= 1; + } + } + } + return crc; +} + + +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]); +} + +uint64_t read_u64_le(const uint8_t* v) { + return ((uint64_t)v[0] + | ((uint64_t)v[1] << 8) + | ((uint64_t)v[2] << 16) + | ((uint64_t)v[3] << 24) + | ((uint64_t)v[4] << 32) + | ((uint64_t)v[5] << 40) + | ((uint64_t)v[6] << 48) + | ((uint64_t)v[7] << 56)); +} diff --git a/can/common.h b/can/common.h new file mode 100644 index 0000000000..4d0e14cbc9 --- /dev/null +++ b/can/common.h @@ -0,0 +1,70 @@ +#pragma once + +#include +#include +#include + +#include "common_dbc.h" +#include +#include "cereal/gen/cpp/log.capnp.h" + +#define MAX_BAD_COUNTER 5 + +// Helper functions +unsigned int honda_checksum(unsigned int address, uint64_t d, int l); +unsigned int toyota_checksum(unsigned int address, uint64_t d, int l); +void init_crc_lookup_tables(); +unsigned int volkswagen_crc(unsigned int address, uint64_t d, int l); +unsigned int pedal_checksum(uint64_t d, int l); +uint64_t read_u64_be(const uint8_t* v); +uint64_t read_u64_le(const uint8_t* v); + +class MessageState { +public: + uint32_t address; + unsigned int size; + + std::vector parse_sigs; + std::vector vals; + + uint16_t ts; + uint64_t seen; + uint64_t check_threshold; + + uint8_t counter; + uint8_t counter_fail; + + bool parse(uint64_t sec, uint16_t ts_, uint8_t * dat); + bool update_counter_generic(int64_t v, int cnt_size); +}; + +class CANParser { +private: + const int bus; + + const DBC *dbc = NULL; + std::unordered_map message_states; + +public: + bool can_valid = false; + uint64_t last_sec = 0; + + CANParser(int abus, const std::string& dbc_name, + const std::vector &options, + const std::vector &sigoptions); + void UpdateCans(uint64_t sec, const capnp::List::Reader& cans); + void UpdateValid(uint64_t sec); + void update_string(std::string data, bool sendcan); + std::vector query_latest(); +}; + +class CANPacker { +private: + const DBC *dbc = NULL; + std::map, Signal> signal_lookup; + std::map message_lookup; + +public: + CANPacker(const std::string& dbc_name); + uint64_t pack(uint32_t address, const std::vector &signals, int counter); +}; diff --git a/can/common.pxd b/can/common.pxd new file mode 100644 index 0000000000..e07e0b35c7 --- /dev/null +++ b/can/common.pxd @@ -0,0 +1,82 @@ +# distutils: language = c++ +#cython: language_level=3 + +from libc.stdint cimport uint32_t, uint64_t, uint16_t +from libcpp.vector cimport vector +from libcpp.map cimport map +from libcpp.string cimport string +from libcpp.unordered_set cimport unordered_set +from libcpp cimport bool + + +cdef extern from "common_dbc.h": + ctypedef enum SignalType: + DEFAULT, + HONDA_CHECKSUM, + HONDA_COUNTER, + TOYOTA_CHECKSUM, + PEDAL_CHECKSUM, + PEDAL_COUNTER, + VOLKSWAGEN_CHECKSUM, + VOLKSWAGEN_COUNTER + + cdef struct Signal: + const char* name + int b1, b2, bo + bool is_signed + double factor, offset + SignalType type + + cdef struct Msg: + const char* name + uint32_t address + unsigned int size + size_t num_sigs + const Signal *sigs + + cdef struct Val: + const char* name + uint32_t address + const char* def_val + const Signal *sigs + + cdef struct DBC: + const char* name + size_t num_msgs + const Msg *msgs + const Val *vals + size_t num_vals + + cdef struct SignalParseOptions: + uint32_t address + const char* name + double default_value + + + cdef struct MessageParseOptions: + uint32_t address + int check_frequency + + cdef struct SignalValue: + uint32_t address + uint16_t ts + const char* name + double value + + cdef struct SignalPackValue: + const char * name + double value + + +cdef extern from "common.h": + cdef const DBC* dbc_lookup(const string); + + cdef cppclass CANParser: + bool can_valid + CANParser(int, string, vector[MessageParseOptions], vector[SignalParseOptions]) + void update_string(string, bool) + vector[SignalValue] query_latest() + + cdef cppclass CANPacker: + CANPacker(string) + uint64_t pack(uint32_t, vector[SignalPackValue], int counter) diff --git a/can/common_dbc.h b/can/common_dbc.h new file mode 100644 index 0000000000..ae6f443ec9 --- /dev/null +++ b/can/common_dbc.h @@ -0,0 +1,82 @@ +#pragma once + +#include +#include +#include + +#define ARRAYSIZE(x) (sizeof(x)/sizeof(x[0])) + +struct SignalPackValue { + const char* name; + double value; +}; + +struct SignalParseOptions { + uint32_t address; + const char* name; + double default_value; +}; + +struct MessageParseOptions { + uint32_t address; + int check_frequency; +}; + +struct SignalValue { + uint32_t address; + uint16_t ts; + const char* name; + double value; +}; + +enum SignalType { + DEFAULT, + HONDA_CHECKSUM, + HONDA_COUNTER, + TOYOTA_CHECKSUM, + PEDAL_CHECKSUM, + PEDAL_COUNTER, + VOLKSWAGEN_CHECKSUM, + VOLKSWAGEN_COUNTER, +}; + +struct Signal { + const char* name; + int b1, b2, bo; + bool is_signed; + double factor, offset; + bool is_little_endian; + SignalType type; +}; + +struct Msg { + const char* name; + uint32_t address; + unsigned int size; + size_t num_sigs; + const Signal *sigs; +}; + +struct Val { + const char* name; + uint32_t address; + const char* def_val; + const Signal *sigs; +}; + +struct DBC { + const char* name; + size_t num_msgs; + const Msg *msgs; + const Val *vals; + size_t num_vals; +}; + +const DBC* dbc_lookup(const std::string& dbc_name); + +void dbc_register(const DBC* dbc); + +#define dbc_init(dbc) \ +static void __attribute__((constructor)) do_dbc_init_ ## dbc(void) { \ + dbc_register(&dbc); \ +} diff --git a/can/dbc.cc b/can/dbc.cc new file mode 100644 index 0000000000..6587de7fe0 --- /dev/null +++ b/can/dbc.cc @@ -0,0 +1,31 @@ +#include + +#include "common_dbc.h" + +namespace { + +std::vector& get_dbcs() { + static std::vector vec; + return vec; +} + +} + +const DBC* dbc_lookup(const std::string& dbc_name) { + for (const auto& dbci : get_dbcs()) { + if (dbc_name == dbci->name) { + return dbci; + } + } + return NULL; +} + +void dbc_register(const DBC* dbc) { + get_dbcs().push_back(dbc); +} + +extern "C" { + const DBC* dbc_lookup(const char* dbc_name) { + return dbc_lookup(std::string(dbc_name)); + } +} diff --git a/can/dbc.py b/can/dbc.py new file mode 100755 index 0000000000..ed5ea74851 --- /dev/null +++ b/can/dbc.py @@ -0,0 +1,275 @@ +import re +import os +import struct +import sys +import numbers +from collections import namedtuple, defaultdict + +def int_or_float(s): + # return number, trying to maintain int format + if s.isdigit(): + return int(s, 10) + else: + return float(s) + +DBCSignal = namedtuple( + "DBCSignal", ["name", "start_bit", "size", "is_little_endian", "is_signed", + "factor", "offset", "tmin", "tmax", "units"]) + + +class dbc(): + def __init__(self, fn): + self.name, _ = os.path.splitext(os.path.basename(fn)) + with open(fn, encoding="ascii") as f: + self.txt = f.readlines() + self._warned_addresses = set() + + # regexps from https://github.com/ebroecker/canmatrix/blob/master/canmatrix/importdbc.py + bo_regexp = re.compile(r"^BO\_ (\w+) (\w+) *: (\w+) (\w+)") + sg_regexp = re.compile(r"^SG\_ (\w+) : (\d+)\|(\d+)@(\d+)([\+|\-]) \(([0-9.+\-eE]+),([0-9.+\-eE]+)\) \[([0-9.+\-eE]+)\|([0-9.+\-eE]+)\] \"(.*)\" (.*)") + sgm_regexp = re.compile(r"^SG\_ (\w+) (\w+) *: (\d+)\|(\d+)@(\d+)([\+|\-]) \(([0-9.+\-eE]+),([0-9.+\-eE]+)\) \[([0-9.+\-eE]+)\|([0-9.+\-eE]+)\] \"(.*)\" (.*)") + val_regexp = re.compile(r"VAL\_ (\w+) (\w+) (\s*[-+]?[0-9]+\s+\".+?\"[^;]*)") + + # A dictionary which maps message ids to tuples ((name, size), signals). + # name is the ASCII name of the message. + # size is the size of the message in bytes. + # signals is a list signals contained in the message. + # signals is a list of DBCSignal in order of increasing start_bit. + self.msgs = {} + + # A dictionary which maps message ids to a list of tuples (signal name, definition value pairs) + self.def_vals = defaultdict(list) + + # lookup to bit reverse each byte + self.bits_index = [(i & ~0b111) + ((-i-1) & 0b111) for i in range(64)] + + for l in self.txt: + l = l.strip() + + if l.startswith("BO_ "): + # new group + dat = bo_regexp.match(l) + + if dat is None: + print("bad BO {0}".format(l)) + + name = dat.group(2) + size = int(dat.group(3)) + ids = int(dat.group(1), 0) # could be hex + if ids in self.msgs: + sys.exit("Duplicate address detected %d %s" % (ids, self.name)) + + self.msgs[ids] = ((name, size), []) + + if l.startswith("SG_ "): + # new signal + dat = sg_regexp.match(l) + go = 0 + if dat is None: + dat = sgm_regexp.match(l) + go = 1 + + if dat is None: + print("bad SG {0}".format(l)) + + sgname = dat.group(1) + start_bit = int(dat.group(go+2)) + signal_size = int(dat.group(go+3)) + is_little_endian = int(dat.group(go+4))==1 + is_signed = dat.group(go+5)=='-' + factor = int_or_float(dat.group(go+6)) + offset = int_or_float(dat.group(go+7)) + tmin = int_or_float(dat.group(go+8)) + tmax = int_or_float(dat.group(go+9)) + units = dat.group(go+10) + + self.msgs[ids][1].append( + DBCSignal(sgname, start_bit, signal_size, is_little_endian, + is_signed, factor, offset, tmin, tmax, units)) + + if l.startswith("VAL_ "): + # new signal value/definition + dat = val_regexp.match(l) + + if dat is None: + print("bad VAL {0}".format(l)) + + ids = int(dat.group(1), 0) # could be hex + sgname = dat.group(2) + defvals = dat.group(3) + + defvals = defvals.replace("?",r"\?") #escape sequence in C++ + defvals = defvals.split('"')[:-1] + + # convert strings to UPPER_CASE_WITH_UNDERSCORES + defvals[1::2] = [d.strip().upper().replace(" ","_") for d in defvals[1::2]] + defvals = '"'+"".join(str(i) for i in defvals)+'"' + + self.def_vals[ids].append((sgname, defvals)) + + for msg in self.msgs.values(): + msg[1].sort(key=lambda x: x.start_bit) + + self.msg_name_to_address = {} + for address, m in self.msgs.items(): + name = m[0][0] + self.msg_name_to_address[name] = address + + def lookup_msg_id(self, msg_id): + if not isinstance(msg_id, numbers.Number): + msg_id = self.msg_name_to_address[msg_id] + return msg_id + + def reverse_bytes(self, x): + return ((x & 0xff00000000000000) >> 56) | \ + ((x & 0x00ff000000000000) >> 40) | \ + ((x & 0x0000ff0000000000) >> 24) | \ + ((x & 0x000000ff00000000) >> 8) | \ + ((x & 0x00000000ff000000) << 8) | \ + ((x & 0x0000000000ff0000) << 24) | \ + ((x & 0x000000000000ff00) << 40) | \ + ((x & 0x00000000000000ff) << 56) + + def encode(self, msg_id, dd): + """Encode a CAN message using the dbc. + + Inputs: + msg_id: The message ID. + dd: A dictionary mapping signal name to signal data. + """ + msg_id = self.lookup_msg_id(msg_id) + + msg_def = self.msgs[msg_id] + size = msg_def[0][1] + + result = 0 + for s in msg_def[1]: + ival = dd.get(s.name) + if ival is not None: + + ival = (ival / s.factor) - s.offset + ival = int(round(ival)) + + if s.is_signed and ival < 0: + ival = (1 << s.size) + ival + + if s.is_little_endian: + shift = s.start_bit + else: + b1 = (s.start_bit // 8) * 8 + (-s.start_bit - 1) % 8 + shift = 64 - (b1 + s.size) + + mask = ((1 << s.size) - 1) << shift + dat = (ival & ((1 << s.size) - 1)) << shift + + if s.is_little_endian: + mask = self.reverse_bytes(mask) + dat = self.reverse_bytes(dat) + + result &= ~mask + result |= dat + + result = struct.pack('>Q', result) + return result[:size] + + def decode(self, x, arr=None, debug=False): + """Decode a CAN message using the dbc. + + Inputs: + x: A collection with elements (address, time, data), where address is + the CAN address, time is the bus time, and data is the CAN data as a + hex string. + arr: Optional list of signals which should be decoded and returned. + debug: True to print debugging statements. + + Returns: + A tuple (name, data), where name is the name of the CAN message and data + is the decoded result. If arr is None, data is a dict of properties. + Otherwise data is a list of the same length as arr. + + Returns (None, None) if the message could not be decoded. + """ + + if arr is None: + out = {} + else: + out = [None]*len(arr) + + msg = self.msgs.get(x[0]) + if msg is None: + if x[0] not in self._warned_addresses: + #print("WARNING: Unknown message address {}".format(x[0])) + self._warned_addresses.add(x[0]) + return None, None + + name = msg[0][0] + if debug: + print(name) + + st = x[2].ljust(8, b'\x00') + le, be = None, None + + for s in msg[1]: + if arr is not None and s[0] not in arr: + continue + + start_bit = s[1] + signal_size = s[2] + little_endian = s[3] + signed = s[4] + factor = s[5] + offset = s[6] + + if little_endian: + if le is None: + le = struct.unpack("Q", st)[0] + tmp = be + b1 = (start_bit // 8) * 8 + (-start_bit - 1) % 8 + shift_amount = 64 - (b1 + signal_size) + + if shift_amount < 0: + continue + + tmp = (tmp >> shift_amount) & ((1 << signal_size) - 1) + if signed and (tmp >> (signal_size - 1)): + tmp -= (1 << signal_size) + + tmp = tmp * factor + offset + + # if debug: + # print("%40s %2d %2d %7.2f %s" % (s[0], s[1], s[2], tmp, s[-1])) + + if arr is None: + out[s[0]] = tmp + else: + out[arr.index(s[0])] = tmp + return name, out + + def get_signals(self, msg): + msg = self.lookup_msg_id(msg) + return [sgs.name for sgs in self.msgs[msg][1]] + + +if __name__ == "__main__": + from opendbc import DBC_PATH + + dbc_test = dbc(os.path.join(DBC_PATH, 'toyota_prius_2017_pt_generated.dbc')) + msg = ('STEER_ANGLE_SENSOR', {'STEER_ANGLE': -6.0, 'STEER_RATE': 4, 'STEER_FRACTION': -0.2}) + encoded = dbc_test.encode(*msg) + decoded = dbc_test.decode((0x25, 0, encoded)) + assert decoded == msg + + dbc_test = dbc(os.path.join(DBC_PATH, 'hyundai_santa_fe_2019_ccan.dbc')) + decoded = dbc_test.decode((0x2b0, 0, "\xfa\xfe\x00\x07\x12")) + assert abs(decoded[1]['SAS_Angle'] - (-26.2)) < 0.001 + + msg = ('SAS11', {'SAS_Stat': 7.0, 'MsgCount': 0.0, 'SAS_Angle': -26.200000000000003, 'SAS_Speed': 0.0, 'CheckSum': 0.0}) + encoded = dbc_test.encode(*msg) + decoded = dbc_test.decode((0x2b0, 0, encoded)) + + assert decoded == msg diff --git a/can/dbc_out/.gitignore b/can/dbc_out/.gitignore new file mode 100644 index 0000000000..4625581a85 --- /dev/null +++ b/can/dbc_out/.gitignore @@ -0,0 +1,2 @@ +*.cc + diff --git a/can/dbc_out/.gitkeep b/can/dbc_out/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/can/dbc_template.cc b/can/dbc_template.cc new file mode 100644 index 0000000000..f9540fcee9 --- /dev/null +++ b/can/dbc_template.cc @@ -0,0 +1,81 @@ +#include "common_dbc.h" + +namespace { + +{% for address, msg_name, msg_size, sigs in msgs %} +const Signal sigs_{{address}}[] = { + {% for sig in sigs %} + { + {% if sig.is_little_endian %} + {% set b1 = sig.start_bit %} + {% else %} + {% set b1 = (sig.start_bit//8)*8 + (-sig.start_bit-1) % 8 %} + {% endif %} + .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}}, + .is_little_endian = {{"true" if sig.is_little_endian else "false"}}, + {% if checksum_type == "honda" and sig.name == "CHECKSUM" %} + .type = SignalType::HONDA_CHECKSUM, + {% elif checksum_type == "honda" and sig.name == "COUNTER" %} + .type = SignalType::HONDA_COUNTER, + {% elif checksum_type == "toyota" and sig.name == "CHECKSUM" %} + .type = SignalType::TOYOTA_CHECKSUM, + {% elif checksum_type == "volkswagen" and sig.name == "CHECKSUM" %} + .type = SignalType::VOLKSWAGEN_CHECKSUM, + {% elif checksum_type == "volkswagen" and sig.name == "COUNTER" %} + .type = SignalType::VOLKSWAGEN_COUNTER, + {% elif address in [512, 513] and sig.name == "CHECKSUM_PEDAL" %} + .type = SignalType::PEDAL_CHECKSUM, + {% elif address in [512, 513] and sig.name == "COUNTER_PEDAL" %} + .type = SignalType::PEDAL_COUNTER, + {% else %} + .type = SignalType::DEFAULT, + {% endif %} + }, + {% endfor %} +}; +{% endfor %} + +const Msg msgs[] = { +{% for address, msg_name, msg_size, sigs in msgs %} + {% set address_hex = "0x%X" % address %} + { + .name = "{{msg_name}}", + .address = {{address_hex}}, + .size = {{msg_size}}, + .num_sigs = ARRAYSIZE(sigs_{{address}}), + .sigs = sigs_{{address}}, + }, +{% endfor %} +}; + +const Val vals[] = { +{% for address, sig in def_vals %} + {% for sg_name, def_val in sig %} + {% set address_hex = "0x%X" % address %} + { + .name = "{{sg_name}}", + .address = {{address_hex}}, + .def_val = {{def_val}}, + .sigs = sigs_{{address}}, + }, + {% endfor %} +{% endfor %} +}; + +} + +const DBC {{dbc.name}} = { + .name = "{{dbc.name}}", + .num_msgs = ARRAYSIZE(msgs), + .msgs = msgs, + .vals = vals, + .num_vals = ARRAYSIZE(vals), +}; + +dbc_init({{dbc.name}}) diff --git a/can/packer.cc b/can/packer.cc new file mode 100644 index 0000000000..fb81952768 --- /dev/null +++ b/can/packer.cc @@ -0,0 +1,108 @@ +#include +#include +#include +#include +#include + +#include "common.h" + +#define WARN printf + +// this is the same as read_u64_le, but uses uint64_t as in/out +uint64_t ReverseBytes(uint64_t x) { + return ((x & 0xff00000000000000ull) >> 56) | + ((x & 0x00ff000000000000ull) >> 40) | + ((x & 0x0000ff0000000000ull) >> 24) | + ((x & 0x000000ff00000000ull) >> 8) | + ((x & 0x00000000ff000000ull) << 8) | + ((x & 0x0000000000ff0000ull) << 24) | + ((x & 0x000000000000ff00ull) << 40) | + ((x & 0x00000000000000ffull) << 56); +} + +uint64_t set_value(uint64_t ret, Signal sig, int64_t ival){ + int shift = sig.is_little_endian? sig.b1 : sig.bo; + uint64_t mask = ((1ULL << sig.b2)-1) << shift; + uint64_t dat = (ival & ((1ULL << sig.b2)-1)) << shift; + if (sig.is_little_endian) { + dat = ReverseBytes(dat); + mask = ReverseBytes(mask); + } + ret &= ~mask; + ret |= dat; + return ret; +} + +CANPacker::CANPacker(const std::string& dbc_name) { + dbc = dbc_lookup(dbc_name); + assert(dbc); + + for (int i=0; inum_msgs; i++) { + const Msg* msg = &dbc->msgs[i]; + message_lookup[msg->address] = *msg; + for (int j=0; jnum_sigs; j++) { + const Signal* sig = &msg->sigs[j]; + signal_lookup[std::make_pair(msg->address, std::string(sig->name))] = *sig; + } + } + init_crc_lookup_tables(); +} + +uint64_t CANPacker::pack(uint32_t address, const std::vector &signals, int counter) { + uint64_t ret = 0; + for (const auto& sigval : signals) { + std::string name = std::string(sigval.name); + double value = sigval.value; + + auto sig_it = signal_lookup.find(std::make_pair(address, name)); + if (sig_it == signal_lookup.end()) { + WARN("undefined signal %s - %d\n", name.c_str(), address); + continue; + } + auto sig = sig_it->second; + + int64_t ival = (int64_t)(round((value - sig.offset) / sig.factor)); + if (ival < 0) { + ival = (1ULL << sig.b2) + ival; + } + + ret = set_value(ret, sig, ival); + } + + if (counter >= 0){ + auto sig_it = signal_lookup.find(std::make_pair(address, "COUNTER")); + if (sig_it == signal_lookup.end()) { + WARN("COUNTER not defined\n"); + return ret; + } + auto sig = sig_it->second; + + if ((sig.type != SignalType::HONDA_COUNTER) && (sig.type != SignalType::VOLKSWAGEN_COUNTER)) { + WARN("COUNTER signal type not valid\n"); + } + + ret = set_value(ret, sig, counter); + } + + auto sig_it_checksum = signal_lookup.find(std::make_pair(address, "CHECKSUM")); + if (sig_it_checksum != signal_lookup.end()) { + auto sig = sig_it_checksum->second; + if (sig.type == SignalType::HONDA_CHECKSUM) { + unsigned int chksm = honda_checksum(address, ret, message_lookup[address].size); + ret = set_value(ret, sig, chksm); + } else if (sig.type == SignalType::TOYOTA_CHECKSUM) { + unsigned int chksm = toyota_checksum(address, ret, message_lookup[address].size); + ret = set_value(ret, sig, chksm); + } else if (sig.type == SignalType::VOLKSWAGEN_CHECKSUM) { + // FIXME: Hackish fix for an endianness issue. The message is in reverse byte order + // until later in the pack process. Checksums can be run backwards, CRCs not so much. + // The correct fix is unclear but this works for the moment. + unsigned int chksm = volkswagen_crc(address, ReverseBytes(ret), message_lookup[address].size); + ret = set_value(ret, sig, chksm); + } else { + //WARN("CHECKSUM signal type not valid\n"); + } + } + + return ret; +} diff --git a/can/packer.py b/can/packer.py new file mode 100644 index 0000000000..fc22cce005 --- /dev/null +++ b/can/packer.py @@ -0,0 +1,3 @@ +# pylint: skip-file +from opendbc.can.packer_pyx import CANPacker +assert CANPacker diff --git a/can/packer_pyx.pyx b/can/packer_pyx.pyx new file mode 100644 index 0000000000..00f83eca65 --- /dev/null +++ b/can/packer_pyx.pyx @@ -0,0 +1,67 @@ +# distutils: language = c++ +# cython: c_string_encoding=ascii, language_level=3 + +from libc.stdint cimport uint32_t, uint64_t +from libcpp.vector cimport vector +from libcpp.map cimport map +from libcpp.string cimport string +from libcpp cimport bool +from posix.dlfcn cimport dlopen, dlsym, RTLD_LAZY + +from common cimport CANPacker as cpp_CANPacker +from common cimport dbc_lookup, SignalPackValue, DBC + + +cdef class CANPacker: + cdef: + cpp_CANPacker *packer + const DBC *dbc + map[string, (int, int)] name_to_address_and_size + map[int, int] address_to_size + + def __init__(self, dbc_name): + self.packer = new cpp_CANPacker(dbc_name) + self.dbc = dbc_lookup(dbc_name) + + num_msgs = self.dbc[0].num_msgs + for i in range(num_msgs): + msg = self.dbc[0].msgs[i] + self.name_to_address_and_size[string(msg.name)] = (msg.address, msg.size) + self.address_to_size[msg.address] = msg.size + + cdef uint64_t pack(self, addr, values, counter): + cdef vector[SignalPackValue] values_thing + cdef SignalPackValue spv + + names = [] + + for name, value in values.iteritems(): + n = name.encode('utf8') + names.append(n) # TODO: find better way to keep reference to temp string arround + + spv.name = n + spv.value = value + values_thing.push_back(spv) + + return self.packer.pack(addr, values_thing, counter) + + cdef inline uint64_t ReverseBytes(self, uint64_t x): + return (((x & 0xff00000000000000ull) >> 56) | + ((x & 0x00ff000000000000ull) >> 40) | + ((x & 0x0000ff0000000000ull) >> 24) | + ((x & 0x000000ff00000000ull) >> 8) | + ((x & 0x00000000ff000000ull) << 8) | + ((x & 0x0000000000ff0000ull) << 24) | + ((x & 0x000000000000ff00ull) << 40) | + ((x & 0x00000000000000ffull) << 56)) + + cpdef make_can_msg(self, name_or_addr, bus, values, counter=-1): + cdef int addr, size + if type(name_or_addr) == int: + addr = name_or_addr + size = self.address_to_size[name_or_addr] + else: + addr, size = self.name_to_address_and_size[name_or_addr.encode('utf8')] + cdef uint64_t val = self.pack(addr, values, counter) + val = self.ReverseBytes(val) + return [addr, 0, (&val)[:size], bus] diff --git a/can/packer_pyx_setup.py b/can/packer_pyx_setup.py new file mode 100644 index 0000000000..6f7a47d0ae --- /dev/null +++ b/can/packer_pyx_setup.py @@ -0,0 +1,60 @@ +import os +import sysconfig +import subprocess +from distutils.core import Extension, setup # pylint: disable=import-error,no-name-in-module + +from Cython.Build import cythonize +from Cython.Distutils import build_ext + +BASEDIR = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../../")) + + +def get_ext_filename_without_platform_suffix(filename): + name, ext = os.path.splitext(filename) + ext_suffix = sysconfig.get_config_var('EXT_SUFFIX') + + if ext_suffix == ext: + return filename + + ext_suffix = ext_suffix.replace(ext, '') + idx = name.find(ext_suffix) + + if idx == -1: + return filename + else: + return name[:idx] + ext + + +class BuildExtWithoutPlatformSuffix(build_ext): + def get_ext_filename(self, ext_name): + filename = super().get_ext_filename(ext_name) + return get_ext_filename_without_platform_suffix(filename) + + +sourcefiles = ['packer_pyx.pyx'] +extra_compile_args = ["-std=c++11"] +ARCH = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip() # pylint: disable=unexpected-keyword-arg + +if ARCH == "aarch64": + extra_compile_args += ["-Wno-deprecated-register"] + + +setup(name='CAN packer', + cmdclass={'build_ext': BuildExtWithoutPlatformSuffix}, + ext_modules=cythonize( + Extension( + "packer_pyx", + language="c++", + sources=sourcefiles, + extra_compile_args=extra_compile_args, + include_dirs=[ + BASEDIR, + os.path.join(BASEDIR, 'phonelibs', 'capnp-cpp/include'), + ], + extra_link_args=[ + os.path.join(BASEDIR, 'opendbc', 'can', 'libdbc.so'), + ], + ) + ), + nthreads=4, +) diff --git a/can/parser.cc b/can/parser.cc new file mode 100644 index 0000000000..69fe3747a2 --- /dev/null +++ b/can/parser.cc @@ -0,0 +1,239 @@ +#include +#include + +#include +#include +#include +#include +#include + +#include "common.h" + +#define DEBUG(...) +// #define DEBUG printf +#define INFO printf + + +bool MessageState::parse(uint64_t sec, uint16_t ts_, uint8_t * dat) { + uint64_t dat_le = read_u64_le(dat); + uint64_t dat_be = read_u64_be(dat); + + for (int i=0; i < parse_sigs.size(); i++) { + auto& sig = parse_sigs[i]; + int64_t tmp; + + if (sig.is_little_endian){ + tmp = (dat_le >> sig.b1) & ((1ULL << sig.b2)-1); + } else { + tmp = (dat_be >> sig.bo) & ((1ULL << sig.b2)-1); + } + + if (sig.is_signed) { + tmp -= (tmp >> (sig.b2-1)) ? (1ULL << sig.b2) : 0; //signed + } + + DEBUG("parse 0x%X %s -> %lld\n", address, sig.name, tmp); + + if (sig.type == SignalType::HONDA_CHECKSUM) { + if (honda_checksum(address, dat_be, size) != tmp) { + INFO("0x%X CHECKSUM FAIL\n", address); + return false; + } + } else if (sig.type == SignalType::HONDA_COUNTER) { + if (!update_counter_generic(tmp, sig.b2)) { + return false; + } + } else if (sig.type == SignalType::TOYOTA_CHECKSUM) { + if (toyota_checksum(address, dat_be, size) != tmp) { + INFO("0x%X CHECKSUM FAIL\n", address); + return false; + } + } else if (sig.type == SignalType::VOLKSWAGEN_CHECKSUM) { + if (volkswagen_crc(address, dat_le, size) != tmp) { + INFO("0x%X CRC FAIL\n", address); + return false; + } + } else if (sig.type == SignalType::VOLKSWAGEN_COUNTER) { + if (!update_counter_generic(tmp, sig.b2)) { + return false; + } + } else if (sig.type == SignalType::PEDAL_CHECKSUM) { + if (pedal_checksum(dat_be, size) != tmp) { + INFO("0x%X PEDAL CHECKSUM FAIL\n", address); + return false; + } + } else if (sig.type == SignalType::PEDAL_COUNTER) { + if (!update_counter_generic(tmp, sig.b2)) { + return false; + } + } + + vals[i] = tmp * sig.factor + sig.offset; + } + ts = ts_; + seen = sec; + + return true; +} + + +bool MessageState::update_counter_generic(int64_t v, int cnt_size) { + uint8_t old_counter = counter; + counter = v; + if (((old_counter+1) & ((1 << cnt_size) -1)) != v) { + counter_fail += 1; + if (counter_fail > 1) { + INFO("0x%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; +} + + +CANParser::CANParser(int abus, const std::string& dbc_name, + const std::vector &options, + const std::vector &sigoptions) + : bus(abus) { + + dbc = dbc_lookup(dbc_name); + assert(dbc); + init_crc_lookup_tables(); + + for (const 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; inum_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 DBC %s\n", op.address, dbc_name.c_str()); + assert(false); + } + + state.size = msg->size; + + // track checksums and counters for this message + for (int i=0; inum_sigs; i++) { + const Signal *sig = &msg->sigs[i]; + if (sig->type != SignalType::DEFAULT) { + state.parse_sigs.push_back(*sig); + state.vals.push_back(0); + } + } + + // track requested signals for this message + for (const auto& sigop : sigoptions) { + if (sigop.address != op.address) continue; + + for (int i=0; inum_sigs; i++) { + const Signal *sig = &msg->sigs[i]; + if (strcmp(sig->name, sigop.name) == 0 + && sig->type == SignalType::DEFAULT) { + state.parse_sigs.push_back(*sig); + state.vals.push_back(sigop.default_value); + break; + } + } + + } + + message_states[state.address] = state; + } +} + +void CANParser::UpdateCans(uint64_t sec, const capnp::List::Reader& cans) { + int msg_count = cans.size(); + uint64_t p; + + 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()); + + state_it->second.parse(sec, cmsg.getBusTime(), dat); + } +} + +void CANParser::UpdateValid(uint64_t sec) { + can_valid = true; + for (const auto& kv : message_states) { + const auto& state = kv.second; + if (state.check_threshold > 0 && (sec - state.seen) > state.check_threshold) { + if (state.seen > 0) { + DEBUG("0x%X TIMEOUT\n", state.address); + } + can_valid = false; + } + } +} + +void CANParser::update_string(std::string data, bool sendcan) { + // format for board, make copy due to alignment issues, will be freed on out of scope + auto amsg = kj::heapArray((data.length() / sizeof(capnp::word)) + 1); + memcpy(amsg.begin(), data.data(), data.length()); + + // extract the messages + capnp::FlatArrayMessageReader cmsg(amsg); + cereal::Event::Reader event = cmsg.getRoot(); + + last_sec = event.getLogMonoTime(); + + auto cans = sendcan? event.getSendcan() : event.getCan(); + UpdateCans(last_sec, cans); + + UpdateValid(last_sec); +} + + +std::vector CANParser::query_latest() { + std::vector ret; + + for (const auto& kv : message_states) { + const auto& state = kv.second; + if (last_sec != 0 && state.seen != last_sec) continue; + + for (int i=0; iself.address_to_msg_name[cv.address].c_str() + cv_name = cv.name + + self.vl[cv.address][cv_name] = cv.value + self.ts[cv.address][cv_name] = cv.ts + + self.vl[name][cv_name] = cv.value + self.ts[name][cv_name] = cv.ts + + updated_val.insert(cv.address) + + return updated_val + + def update_string(self, dat, sendcan=False): + self.can.update_string(dat, sendcan) + return self.update_vl() + + def update_strings(self, strings, sendcan=False): + updated_vals = set() + + for s in strings: + updated_val = self.update_string(s, sendcan) + updated_vals.update(updated_val) + + return updated_vals + +cdef class CANDefine(): + cdef: + const DBC *dbc + + cdef public: + dict dv + string dbc_name + + def __init__(self, dbc_name): + self.dbc_name = dbc_name + self.dbc = dbc_lookup(dbc_name) + + num_vals = self.dbc[0].num_vals + + address_to_msg_name = {} + + num_msgs = self.dbc[0].num_msgs + for i in range(num_msgs): + msg = self.dbc[0].msgs[i] + name = msg.name.decode('utf8') + address = msg.address + address_to_msg_name[address] = name + + dv = defaultdict(dict) + + for i in range(num_vals): + val = self.dbc[0].vals[i] + + sgname = val.name.decode('utf8') + address = val.address + def_val = val.def_val.decode('utf8') + + #separate definition/value pairs + def_val = def_val.split() + values = [int(v) for v in def_val[::2]] + defs = def_val[1::2] + + if address not in dv: + dv[address] = {} + msgname = address_to_msg_name[address] + dv[msgname] = {} + + # two ways to lookup: address or msg name + dv[address][sgname] = dict(zip(values, defs)) + dv[msgname][sgname] = dv[address][sgname] + + self.dv = dict(dv) diff --git a/can/parser_pyx_setup.py b/can/parser_pyx_setup.py new file mode 100644 index 0000000000..8ce6e7e7b4 --- /dev/null +++ b/can/parser_pyx_setup.py @@ -0,0 +1,59 @@ +import os +import subprocess +import sysconfig +from distutils.core import Extension, setup # pylint: disable=import-error,no-name-in-module + +from Cython.Build import cythonize +from Cython.Distutils import build_ext + +BASEDIR = os.path.abspath(os.path.join(os.path.dirname(os.path.realpath(__file__)), "../../")) + + +def get_ext_filename_without_platform_suffix(filename): + name, ext = os.path.splitext(filename) + ext_suffix = sysconfig.get_config_var('EXT_SUFFIX') + + if ext_suffix == ext: + return filename + + ext_suffix = ext_suffix.replace(ext, '') + idx = name.find(ext_suffix) + + if idx == -1: + return filename + else: + return name[:idx] + ext + + +class BuildExtWithoutPlatformSuffix(build_ext): + def get_ext_filename(self, ext_name): + filename = super().get_ext_filename(ext_name) + return get_ext_filename_without_platform_suffix(filename) + + +sourcefiles = ['parser_pyx.pyx'] +extra_compile_args = ["-std=c++11"] +ARCH = subprocess.check_output(["uname", "-m"], encoding='utf8').rstrip() # pylint: disable=unexpected-keyword-arg + +if ARCH == "aarch64": + extra_compile_args += ["-Wno-deprecated-register"] + +setup(name='CAN parser', + cmdclass={'build_ext': BuildExtWithoutPlatformSuffix}, + ext_modules=cythonize( + Extension( + "parser_pyx", + language="c++", + sources=sourcefiles, + extra_compile_args=extra_compile_args, + include_dirs=[ + BASEDIR, + os.path.join(BASEDIR, 'phonelibs', 'capnp-cpp/include'), + ], + extra_link_args=[ + os.path.join(BASEDIR, 'opendbc', 'can', 'libdbc.so'), + ], + ) + ), + nthreads=4, +) diff --git a/can/process_dbc.py b/can/process_dbc.py new file mode 100755 index 0000000000..a1c91a8978 --- /dev/null +++ b/can/process_dbc.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python3 +from __future__ import print_function +import os +import sys + +import jinja2 + +from collections import Counter +from opendbc.can.dbc import dbc + +def process(in_fn, out_fn): + dbc_name = os.path.split(out_fn)[-1].replace('.cc', '') + #print("processing %s: %s -> %s" % (dbc_name, in_fn, out_fn)) + + template_fn = os.path.join(os.path.dirname(__file__), "dbc_template.cc") + + with open(template_fn, "r") as template_f: + template = jinja2.Template(template_f.read(), trim_blocks=True, lstrip_blocks=True) + + can_dbc = dbc(in_fn) + + msgs = [(address, msg_name, msg_size, sorted(msg_sigs, key=lambda s: s.name not in ("COUNTER", "CHECKSUM"))) # process counter and checksums first + for address, ((msg_name, msg_size), msg_sigs) in sorted(can_dbc.msgs.items()) if msg_sigs] + + def_vals = {a: sorted(set(b)) for a, b in can_dbc.def_vals.items()} # remove duplicates + def_vals = sorted(def_vals.items()) + + if can_dbc.name.startswith(("honda_", "acura_")): + checksum_type = "honda" + checksum_size = 4 + counter_size = 2 + checksum_start_bit = 3 + counter_start_bit = 5 + little_endian = False + elif can_dbc.name.startswith(("toyota_", "lexus_")): + checksum_type = "toyota" + checksum_size = 8 + counter_size = None + checksum_start_bit = 7 + counter_start_bit = None + little_endian = False + elif can_dbc.name.startswith(("vw_", "volkswagen_", "audi_", "seat_", "skoda_")): + checksum_type = "volkswagen" + checksum_size = 8 + counter_size = 4 + checksum_start_bit = 0 + counter_start_bit = 0 + little_endian = True + else: + checksum_type = None + checksum_size = None + counter_size = None + checksum_start_bit = None + counter_start_bit = None + little_endian = None + + # sanity checks on expected COUNTER and CHECKSUM rules, as packer and parser auto-compute those signals + for address, msg_name, msg_size, sigs in msgs: + dbc_msg_name = dbc_name + " " + msg_name + for sig in sigs: + if checksum_type is not None: + # checksum rules + if sig.name == "CHECKSUM": + if sig.size != checksum_size: + sys.exit("%s: CHECKSUM is not %d bits long" % (dbc_msg_name, checksum_size)) + if sig.start_bit % 8 != checksum_start_bit: + sys.exit("%s: CHECKSUM starts at wrong bit" % dbc_msg_name) + if little_endian != sig.is_little_endian: + sys.exit("%s: CHECKSUM has wrong endianess" % dbc_msg_name) + # counter rules + if sig.name == "COUNTER": + if counter_size is not None and sig.size != counter_size: + sys.exit("%s: COUNTER is not %d bits long" % (dbc_msg_name, counter_size)) + if counter_start_bit is not None and sig.start_bit % 8 != counter_start_bit: + print(counter_start_bit, sig.start_bit) + sys.exit("%s: COUNTER starts at wrong bit" % dbc_msg_name) + if little_endian != sig.is_little_endian: + sys.exit("%s: COUNTER has wrong endianess" % dbc_msg_name) + # pedal rules + if address in [0x200, 0x201]: + if sig.name == "COUNTER_PEDAL" and sig.size != 4: + sys.exit("%s: PEDAL COUNTER is not 4 bits long" % dbc_msg_name) + if sig.name == "CHECKSUM_PEDAL" and sig.size != 8: + sys.exit("%s: PEDAL CHECKSUM is not 8 bits long" % dbc_msg_name) + + # Fail on duplicate message names + c = Counter([msg_name for address, msg_name, msg_size, sigs in msgs]) + for name, count in c.items(): + if count > 1: + sys.exit("%s: Duplicate message name in DBC file %s" % (dbc_name, name)) + + parser_code = template.render(dbc=can_dbc, checksum_type=checksum_type, msgs=msgs, def_vals=def_vals, len=len) + + with open(out_fn, "w") as out_f: + out_f.write(parser_code) + +def main(): + if len(sys.argv) != 3: + print("usage: %s dbc_directory output_filename" % (sys.argv[0],)) + sys.exit(0) + + dbc_dir = sys.argv[1] + out_fn = sys.argv[2] + + dbc_name = os.path.split(out_fn)[-1].replace('.cc', '') + in_fn = os.path.join(dbc_dir, dbc_name + '.dbc') + + process(in_fn, out_fn) + +if __name__ == '__main__': + main() + diff --git a/can/tests/.gitignore b/can/tests/.gitignore new file mode 100644 index 0000000000..192fb0945e --- /dev/null +++ b/can/tests/.gitignore @@ -0,0 +1 @@ +*.bz2 diff --git a/can/tests/__init__.py b/can/tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/can/tests/linter_python/.pylintrc b/can/tests/linter_python/.pylintrc new file mode 100644 index 0000000000..64a55daf8f --- /dev/null +++ b/can/tests/linter_python/.pylintrc @@ -0,0 +1,585 @@ +[MASTER] + +# A comma-separated list of package or module names from where C extensions may +# be loaded. Extensions are loading into the active Python interpreter and may +# run arbitrary code +extension-pkg-whitelist=scipy + +# Add files or directories to the blacklist. They should be base names, not +# paths. +ignore=CVS + +# Add files or directories matching the regex patterns to the blacklist. The +# regex matches against base names, not paths. +ignore-patterns= + +# Python code to execute, usually for sys.path manipulation such as +# pygtk.require(). +#init-hook= + +# Use multiple processes to speed up Pylint. +jobs=4 + +# List of plugins (as comma separated values of python modules names) to load, +# usually to register additional checkers. +load-plugins= + +# Pickle collected data for later comparisons. +persistent=yes + +# Specify a configuration file. +#rcfile= + +# When enabled, pylint would attempt to guess common misconfiguration and emit +# user-friendly hints instead of false-positive error messages +suggestion-mode=yes + +# Allow loading of arbitrary C extensions. Extensions are imported into the +# active Python interpreter and may run arbitrary code. +unsafe-load-any-extension=no + + +[MESSAGES CONTROL] + +# Only show warnings with the listed confidence levels. Leave empty to show +# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED +confidence= + +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifiers separated by comma (,) or put this +# option multiple times (only on the command line, not in the configuration +# file where it should appear only once).You can also use "--disable=all" to +# disable everything first and then reenable specific checks. For example, if +# you want to run only the similarities checker, you can use "--disable=all +# --enable=similarities". If you want to run only the classes checker, but have +# no Warning level messages displayed, use"--disable=all --enable=classes +# --disable=W" +disable=print-statement, + parameter-unpacking, + unpacking-in-except, + old-raise-syntax, + backtick, + long-suffix, + old-ne-operator, + old-octal-literal, + import-star-module-level, + non-ascii-bytes-literal, + raw-checker-failed, + bad-inline-option, + locally-disabled, + locally-enabled, + file-ignored, + suppressed-message, + useless-suppression, + deprecated-pragma, + apply-builtin, + basestring-builtin, + buffer-builtin, + cmp-builtin, + coerce-builtin, + execfile-builtin, + file-builtin, + long-builtin, + raw_input-builtin, + reduce-builtin, + standarderror-builtin, + unicode-builtin, + xrange-builtin, + coerce-method, + delslice-method, + getslice-method, + setslice-method, + no-absolute-import, + old-division, + dict-iter-method, + dict-view-method, + next-method-called, + metaclass-assignment, + indexing-exception, + raising-string, + reload-builtin, + oct-method, + hex-method, + nonzero-method, + cmp-method, + input-builtin, + round-builtin, + intern-builtin, + unichr-builtin, + map-builtin-not-iterating, + zip-builtin-not-iterating, + range-builtin-not-iterating, + filter-builtin-not-iterating, + using-cmp-argument, + eq-without-hash, + div-method, + idiv-method, + rdiv-method, + exception-message-attribute, + invalid-str-codec, + sys-max-int, + bad-python3-import, + deprecated-string-function, + deprecated-str-translate-call, + deprecated-itertools-function, + deprecated-types-field, + next-method-defined, + dict-items-not-iterating, + dict-keys-not-iterating, + dict-values-not-iterating, + bad-indentation, + line-too-long, + missing-docstring, + multiple-statements, + bad-continuation, + invalid-name, + too-many-arguments, + too-many-locals, + superfluous-parens, + bad-whitespace, + too-many-instance-attributes, + wrong-import-position, + ungrouped-imports, + wrong-import-order, + protected-access, + trailing-whitespace, + too-many-branches, + too-few-public-methods, + too-many-statements, + trailing-newlines, + attribute-defined-outside-init, + too-many-return-statements, + too-many-public-methods, + unused-argument, + old-style-class, + no-init, + len-as-condition, + unneeded-not, + no-self-use, + multiple-imports, + no-else-return, + logging-not-lazy, + fixme, + redefined-outer-name, + unused-variable, + unsubscriptable-object, + expression-not-assigned, + too-many-boolean-expressions, + consider-using-ternary, + invalid-unary-operand-type, + relative-import, + deprecated-lambda + + +# Enable the message, report, category or checker with the given id(s). You can +# either give multiple identifier separated by comma (,) or put this option +# multiple time (only on the command line, not in the configuration file where +# it should appear only once). See also the "--disable" option for examples. +enable=c-extension-no-member + + +[REPORTS] + +# Python expression which should return a note less than 10 (10 is the highest +# note). You have access to the variables errors warning, statement which +# respectively contain the number of errors / warnings messages and the total +# number of statements analyzed. This is used by the global evaluation report +# (RP0004). +evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) + +# Template used to display messages. This is a python new-style format string +# used to format the message information. See doc for all details +#msg-template= + +# Set the output format. Available formats are text, parseable, colorized, json +# and msvs (visual studio).You can also give a reporter class, eg +# mypackage.mymodule.MyReporterClass. +output-format=text + +# Tells whether to display a full report or only the messages +reports=no + +# Activate the evaluation score. +score=yes + + +[REFACTORING] + +# Maximum number of nested blocks for function / method body +max-nested-blocks=5 + +# Complete name of functions that never returns. When checking for +# inconsistent-return-statements if a never returning function is called then +# it will be considered as an explicit return statement and no message will be +# printed. +never-returning-functions=optparse.Values,sys.exit + + +[LOGGING] + +# Logging modules to check that the string format arguments are in logging +# function parameter format +logging-modules=logging + + +[SPELLING] + +# Limits count of emitted suggestions for spelling mistakes +max-spelling-suggestions=4 + +# Spelling dictionary name. Available dictionaries: none. To make it working +# install python-enchant package. +spelling-dict= + +# List of comma separated words that should not be checked. +spelling-ignore-words= + +# A path to a file that contains private dictionary; one word per line. +spelling-private-dict-file= + +# Tells whether to store unknown words to indicated private dictionary in +# --spelling-private-dict-file option instead of raising a message. +spelling-store-unknown-words=no + + +[MISCELLANEOUS] + +# List of note tags to take in consideration, separated by a comma. +notes=FIXME, + XXX, + TODO + + +[SIMILARITIES] + +# Ignore comments when computing similarities. +ignore-comments=yes + +# Ignore docstrings when computing similarities. +ignore-docstrings=yes + +# Ignore imports when computing similarities. +ignore-imports=no + +# Minimum lines number of a similarity. +min-similarity-lines=4 + + +[TYPECHECK] + +# List of decorators that produce context managers, such as +# contextlib.contextmanager. Add to this list to register other decorators that +# produce valid context managers. +contextmanager-decorators=contextlib.contextmanager + +# List of members which are set dynamically and missed by pylint inference +# system, and so shouldn't trigger E1101 when accessed. Python regular +# expressions are accepted. +generated-members=capnp.* cereal.* pygame.* zmq.* setproctitle.* smbus2.* usb1.* serial.* cv2.* + +# Tells whether missing members accessed in mixin class should be ignored. A +# mixin class is detected if its name ends with "mixin" (case insensitive). +ignore-mixin-members=yes + +# This flag controls whether pylint should warn about no-member and similar +# checks whenever an opaque object is returned when inferring. The inference +# can return multiple potential results while evaluating a Python object, but +# some branches might not be evaluated, which results in partial inference. In +# that case, it might be useful to still emit no-member and other checks for +# the rest of the inferred objects. +ignore-on-opaque-inference=yes + +# List of class names for which member attributes should not be checked (useful +# for classes with dynamically set attributes). This supports the use of +# qualified names. +ignored-classes=optparse.Values,thread._local,_thread._local + +# List of module names for which member attributes should not be checked +# (useful for modules/projects where namespaces are manipulated during runtime +# and thus existing member attributes cannot be deduced by static analysis. It +# supports qualified module names, as well as Unix pattern matching. +ignored-modules=flask setproctitle usb1 flask.ext.socketio smbus2 usb1.* + +# Show a hint with possible names when a member name was not found. The aspect +# of finding the hint is based on edit distance. +missing-member-hint=yes + +# The minimum edit distance a name should have in order to be considered a +# similar match for a missing member name. +missing-member-hint-distance=1 + +# The total number of similar names that should be taken in consideration when +# showing a hint for a missing member. +missing-member-max-choices=1 + + +[VARIABLES] + +# List of additional names supposed to be defined in builtins. Remember that +# you should avoid to define new builtins when possible. +additional-builtins= + +# Tells whether unused global variables should be treated as a violation. +allow-global-unused-variables=yes + +# List of strings which can identify a callback function by name. A callback +# name must start or end with one of those strings. +callbacks=cb_, + _cb + +# A regular expression matching the name of dummy variables (i.e. expectedly +# not used). +dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ + +# Argument names that match this expression will be ignored. Default to name +# with leading underscore +ignored-argument-names=_.*|^ignored_|^unused_ + +# Tells whether we should check for unused import in __init__ files. +init-import=no + +# List of qualified module names which can have objects that can redefine +# builtins. +redefining-builtins-modules=six.moves,past.builtins,future.builtins + + +[FORMAT] + +# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. +expected-line-ending-format= + +# Regexp for a line that is allowed to be longer than the limit. +ignore-long-lines=^\s*(# )??$ + +# Number of spaces of indent required inside a hanging or continued line. +indent-after-paren=4 + +# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 +# tab). +indent-string=' ' + +# Maximum number of characters on a single line. +max-line-length=100 + +# Maximum number of lines in a module +max-module-lines=1000 + +# List of optional constructs for which whitespace checking is disabled. `dict- +# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. +# `trailing-comma` allows a space between comma and closing bracket: (a, ). +# `empty-line` allows space-only lines. +no-space-check=trailing-comma, + dict-separator + +# Allow the body of a class to be on the same line as the declaration if body +# contains single statement. +single-line-class-stmt=no + +# Allow the body of an if to be on the same line as the test if there is no +# else. +single-line-if-stmt=no + + +[BASIC] + +# Naming style matching correct argument names +argument-naming-style=snake_case + +# Regular expression matching correct argument names. Overrides argument- +# naming-style +#argument-rgx= + +# Naming style matching correct attribute names +attr-naming-style=snake_case + +# Regular expression matching correct attribute names. Overrides attr-naming- +# style +#attr-rgx= + +# Bad variable names which should always be refused, separated by a comma +bad-names=foo, + bar, + baz, + toto, + tutu, + tata + +# Naming style matching correct class attribute names +class-attribute-naming-style=any + +# Regular expression matching correct class attribute names. Overrides class- +# attribute-naming-style +#class-attribute-rgx= + +# Naming style matching correct class names +class-naming-style=PascalCase + +# Regular expression matching correct class names. Overrides class-naming-style +#class-rgx= + +# Naming style matching correct constant names +const-naming-style=UPPER_CASE + +# Regular expression matching correct constant names. Overrides const-naming- +# style +#const-rgx= + +# Minimum line length for functions/classes that require docstrings, shorter +# ones are exempt. +docstring-min-length=-1 + +# Naming style matching correct function names +function-naming-style=snake_case + +# Regular expression matching correct function names. Overrides function- +# naming-style +#function-rgx= + +# Good variable names which should always be accepted, separated by a comma +good-names=i, + j, + k, + ex, + Run, + _ + +# Include a hint for the correct naming format with invalid-name +include-naming-hint=no + +# Naming style matching correct inline iteration names +inlinevar-naming-style=any + +# Regular expression matching correct inline iteration names. Overrides +# inlinevar-naming-style +#inlinevar-rgx= + +# Naming style matching correct method names +method-naming-style=snake_case + +# Regular expression matching correct method names. Overrides method-naming- +# style +#method-rgx= + +# Naming style matching correct module names +module-naming-style=snake_case + +# Regular expression matching correct module names. Overrides module-naming- +# style +#module-rgx= + +# Colon-delimited sets of names that determine each other's naming style when +# the name regexes allow several styles. +name-group= + +# Regular expression which should only match function or class names that do +# not require a docstring. +no-docstring-rgx=^_ + +# List of decorators that produce properties, such as abc.abstractproperty. Add +# to this list to register other decorators that produce valid properties. +property-classes=abc.abstractproperty + +# Naming style matching correct variable names +variable-naming-style=snake_case + +# Regular expression matching correct variable names. Overrides variable- +# naming-style +#variable-rgx= + + +[DESIGN] + +# Maximum number of arguments for function / method +max-args=5 + +# Maximum number of attributes for a class (see R0902). +max-attributes=7 + +# Maximum number of boolean expressions in a if statement +max-bool-expr=5 + +# Maximum number of branch for function / method body +max-branches=12 + +# Maximum number of locals for function / method body +max-locals=15 + +# Maximum number of parents for a class (see R0901). +max-parents=7 + +# Maximum number of public methods for a class (see R0904). +max-public-methods=20 + +# Maximum number of return / yield for function / method body +max-returns=6 + +# Maximum number of statements in function / method body +max-statements=50 + +# Minimum number of public methods for a class (see R0903). +min-public-methods=2 + + +[CLASSES] + +# List of method names used to declare (i.e. assign) instance attributes. +defining-attr-methods=__init__, + __new__, + setUp + +# List of member names, which should be excluded from the protected access +# warning. +exclude-protected=_asdict, + _fields, + _replace, + _source, + _make + +# List of valid names for the first argument in a class method. +valid-classmethod-first-arg=cls + +# List of valid names for the first argument in a metaclass class method. +valid-metaclass-classmethod-first-arg=mcs + + +[IMPORTS] + +# Allow wildcard imports from modules that define __all__. +allow-wildcard-with-all=no + +# Analyse import fallback blocks. This can be used to support both Python 2 and +# 3 compatible code, which means that the block might have code that exists +# only in one or another interpreter, leading to false positives when analysed. +analyse-fallback-blocks=no + +# Deprecated modules which should not be used, separated by a comma +deprecated-modules=regsub, + TERMIOS, + Bastion, + rexec + +# Create a graph of external dependencies in the given file (report RP0402 must +# not be disabled) +ext-import-graph= + +# Create a graph of every (i.e. internal and external) dependencies in the +# given file (report RP0402 must not be disabled) +import-graph= + +# Create a graph of internal dependencies in the given file (report RP0402 must +# not be disabled) +int-import-graph= + +# Force import order to recognize a module as part of the standard +# compatibility libraries. +known-standard-library= + +# Force import order to recognize a module as part of a third party library. +known-third-party=enchant + + +[EXCEPTIONS] + +# Exceptions that will emit a warning when being caught. Defaults to +# "Exception" +overgeneral-exceptions=Exception diff --git a/can/tests/linter_python/flake8_opendbc.sh b/can/tests/linter_python/flake8_opendbc.sh new file mode 100755 index 0000000000..66402b2367 --- /dev/null +++ b/can/tests/linter_python/flake8_opendbc.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +RESULT=$(python3 -m flake8 --select=F $(find ../../../ -type f | grep "\.py$")) +if [[ $RESULT ]]; then + echo "Pyflakes found errors in the code. Please fix and try again" + echo "$RESULT" + exit 1 +fi diff --git a/can/tests/linter_python/pylint_opendbc.sh b/can/tests/linter_python/pylint_opendbc.sh new file mode 100755 index 0000000000..c2e7efc804 --- /dev/null +++ b/can/tests/linter_python/pylint_opendbc.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +python3 -m pylint --disable=R,C,W $(find ../../../ -type f | grep "\.py$") + +exit_status=$? +(( res = exit_status & 3 )) + +if [[ $res != 0 ]]; then + echo "Pylint found errors in the code. Please fix and try again" + exit 1 +fi diff --git a/can/tests/test_define.py b/can/tests/test_define.py new file mode 100644 index 0000000000..d9a6f7d671 --- /dev/null +++ b/can/tests/test_define.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python3 +import unittest + +from opendbc.can.can_define import CANDefine + + +class TestCADNDefine(unittest.TestCase): + def test_civic(self): + + dbc_file = "honda_civic_touring_2016_can_generated" + defs = CANDefine(dbc_file) + + self.assertDictEqual(defs.dv[399], defs.dv['STEER_STATUS']) + self.assertDictEqual(defs.dv[399], + {'STEER_STATUS': + {6: 'TMP_FAULT', + 5: 'FAULT_1', + 4: 'NO_TORQUE_ALERT_2', + 3: 'LOW_SPEED_LOCKOUT', + 2: 'NO_TORQUE_ALERT_1', + 0: 'NORMAL'} + } + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/can/tests/test_packer_parser.py b/can/tests/test_packer_parser.py new file mode 100644 index 0000000000..1c28e8867c --- /dev/null +++ b/can/tests/test_packer_parser.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python3 + +import unittest + +from opendbc.can.parser import CANParser +from opendbc.can.packer import CANPacker +import cereal.messaging as messaging + + +# Python implementation so we don't have to depend on boardd +def can_list_to_can_capnp(can_msgs, msgtype='can'): + dat = messaging.new_message() + dat.init(msgtype, len(can_msgs)) + + for i, can_msg in enumerate(can_msgs): + if msgtype == 'sendcan': + cc = dat.sendcan[i] + else: + cc = dat.can[i] + + cc.address = can_msg[0] + cc.busTime = can_msg[1] + cc.dat = bytes(can_msg[2]) + cc.src = can_msg[3] + + return dat.to_bytes() + + +class TestCanParserPacker(unittest.TestCase): + def test_civic(self): + + dbc_file = "honda_civic_touring_2016_can_generated" + + signals = [ + ("STEER_TORQUE", "STEERING_CONTROL", 0), + ("STEER_TORQUE_REQUEST", "STEERING_CONTROL", 0), + ] + checks = [] + + parser = CANParser(dbc_file, signals, checks, 0) + packer = CANPacker(dbc_file) + + idx = 0 + + for steer in range(-256, 255): + for active in [1, 0]: + values = { + "STEER_TORQUE": steer, + "STEER_TORQUE_REQUEST": active, + } + + msgs = packer.make_can_msg("STEERING_CONTROL", 0, values, idx) + bts = can_list_to_can_capnp([msgs]) + + parser.update_string(bts) + + self.assertAlmostEqual(parser.vl["STEERING_CONTROL"]["STEER_TORQUE"], steer) + self.assertAlmostEqual(parser.vl["STEERING_CONTROL"]["STEER_TORQUE_REQUEST"], active) + self.assertAlmostEqual(parser.vl["STEERING_CONTROL"]["COUNTER"], idx % 4) + + idx += 1 + + def test_subaru(self): + # Subuaru is little endian + + dbc_file = "subaru_global_2017" + + signals = [ + ("Counter", "ES_LKAS", 0), + ("LKAS_Output", "ES_LKAS", 0), + ("LKAS_Request", "ES_LKAS", 0), + ("SET_1", "ES_LKAS", 0), + + ] + + checks = [] + + parser = CANParser(dbc_file, signals, checks, 0) + packer = CANPacker(dbc_file) + + idx = 0 + + for steer in range(-256, 255): + for active in [1, 0]: + values = { + "Counter": idx, + "LKAS_Output": steer, + "LKAS_Request": active, + "SET_1": 1 + } + + msgs = packer.make_can_msg("ES_LKAS", 0, values) + bts = can_list_to_can_capnp([msgs]) + parser.update_string(bts) + + self.assertAlmostEqual(parser.vl["ES_LKAS"]["LKAS_Output"], steer) + self.assertAlmostEqual(parser.vl["ES_LKAS"]["LKAS_Request"], active) + self.assertAlmostEqual(parser.vl["ES_LKAS"]["SET_1"], 1) + self.assertAlmostEqual(parser.vl["ES_LKAS"]["Counter"], idx % 16) + + idx += 1 + + +if __name__ == "__main__": + unittest.main() diff --git a/generator/honda/_bosch_2018.dbc b/generator/honda/_bosch_2018.dbc index 648f4b310c..19585529f0 100644 --- a/generator/honda/_bosch_2018.dbc +++ b/generator/honda/_bosch_2018.dbc @@ -91,8 +91,8 @@ BO_ 380 POWERTRAIN_DATA: 8 PCM SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON BO_ 399 STEER_STATUS: 7 EPS - SG_ STEER_TORQUE_SENSOR : 7|16@0- (1,0) [-31000|31000] "tbd" EON - SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_SENSOR : 7|16@0- (-1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_MOTOR : 23|16@0- (-1,0) [-31000|31000] "tbd" EON SG_ STEER_STATUS : 39|4@0+ (1,0) [0|15] "" EON SG_ STEER_CONTROL_ACTIVE : 35|1@0+ (1,0) [0|1] "" EON SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON diff --git a/generator/honda/acura_ilx_2016_can.dbc b/generator/honda/acura_ilx_2016_can.dbc index e45426b3a6..df77448204 100644 --- a/generator/honda/acura_ilx_2016_can.dbc +++ b/generator/honda/acura_ilx_2016_can.dbc @@ -26,8 +26,8 @@ BO_ 342 STEERING_SENSORS: 6 EPS SG_ CHECKSUM : 43|4@0+ (1,0) [0|3] "" EON BO_ 399 STEER_STATUS: 7 EPS - SG_ STEER_TORQUE_SENSOR : 7|16@0- (1,0) [-31000|31000] "tbd" EON - SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_SENSOR : 7|16@0- (-1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_MOTOR : 23|16@0- (-1,0) [-31000|31000] "tbd" EON SG_ STEER_STATUS : 39|4@0+ (1,0) [0|15] "" EON SG_ STEER_CONTROL_ACTIVE : 35|1@0+ (1,0) [0|1] "" EON SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON diff --git a/generator/honda/acura_rdx_2018_can.dbc b/generator/honda/acura_rdx_2018_can.dbc index 87389f8b2c..2fccfd1b2e 100644 --- a/generator/honda/acura_rdx_2018_can.dbc +++ b/generator/honda/acura_rdx_2018_can.dbc @@ -14,8 +14,8 @@ BO_ 392 GEARBOX: 6 XXX SG_ GEAR : 36|5@0+ (1,0) [0|31] "" EON BO_ 399 STEER_STATUS: 6 EPS - SG_ STEER_TORQUE_SENSOR : 7|12@0- (1,0) [-2047.5|2047.5] "tbd" EON - SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_SENSOR : 7|12@0- (-1,0) [-2047.5|2047.5] "tbd" EON + SG_ STEER_TORQUE_MOTOR : 23|16@0- (-1,0) [-31000|31000] "tbd" EON SG_ STEER_STATUS : 35|4@0+ (1,0) [0|15] "" EON SG_ STEER_CONTROL_ACTIVE : 36|1@0+ (1,0) [0|1] "" EON SG_ COUNTER : 45|2@0+ (1,0) [0|3] "" EON diff --git a/generator/honda/honda_civic_touring_2016_can.dbc b/generator/honda/honda_civic_touring_2016_can.dbc index 1a7579d2a2..2cce31609d 100644 --- a/generator/honda/honda_civic_touring_2016_can.dbc +++ b/generator/honda/honda_civic_touring_2016_can.dbc @@ -31,8 +31,8 @@ BO_ 330 STEERING_SENSORS: 8 EPS SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON BO_ 399 STEER_STATUS: 7 EPS - SG_ STEER_TORQUE_SENSOR : 7|16@0- (1,0) [-31000|31000] "tbd" EON - SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_SENSOR : 7|16@0- (-1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_MOTOR : 23|16@0- (-1,0) [-31000|31000] "tbd" EON SG_ STEER_STATUS : 39|4@0+ (1,0) [0|15] "" EON SG_ STEER_CONTROL_ACTIVE : 35|1@0+ (1,0) [0|1] "" EON SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON diff --git a/generator/honda/honda_crv_touring_2016_can.dbc b/generator/honda/honda_crv_touring_2016_can.dbc index 3d9b48ab71..b41171d434 100644 --- a/generator/honda/honda_crv_touring_2016_can.dbc +++ b/generator/honda/honda_crv_touring_2016_can.dbc @@ -8,8 +8,8 @@ BO_ 342 STEERING_SENSORS: 6 EPS SG_ CHECKSUM : 43|4@0+ (1,0) [0|15] "" EON BO_ 399 STEER_STATUS: 6 EPS - SG_ STEER_TORQUE_SENSOR : 7|12@0- (1,0) [-2047.5|2047.5] "tbd" EON - SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_SENSOR : 7|12@0- (-1,0) [-2047.5|2047.5] "tbd" EON + SG_ STEER_TORQUE_MOTOR : 23|16@0- (-1,0) [-31000|31000] "tbd" EON SG_ STEER_CONTROL_ACTIVE : 36|1@0+ (1,0) [0|1] "" EON SG_ STEER_STATUS : 35|4@0+ (1,0) [0|15] "" EON SG_ COUNTER : 45|2@0+ (1,0) [0|3] "" EON diff --git a/generator/honda/honda_fit_ex_2018_can.dbc b/generator/honda/honda_fit_ex_2018_can.dbc index ce02d4cf8a..9c2bf64b5a 100644 --- a/generator/honda/honda_fit_ex_2018_can.dbc +++ b/generator/honda/honda_fit_ex_2018_can.dbc @@ -26,8 +26,8 @@ BO_ 342 STEERING_SENSORS: 6 EPS SG_ CHECKSUM : 43|4@0+ (1,0) [0|3] "" EON BO_ 399 STEER_STATUS: 7 EPS - SG_ STEER_TORQUE_SENSOR : 7|16@0- (1,0) [-31000|31000] "tbd" EON - SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_SENSOR : 7|16@0- (-1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_MOTOR : 23|16@0- (-1,0) [-31000|31000] "tbd" EON SG_ STEER_STATUS : 39|4@0+ (1,0) [0|15] "" EON SG_ STEER_CONTROL_ACTIVE : 35|1@0+ (1,0) [0|1] "" EON SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON diff --git a/generator/honda/honda_fit_hybrid_2018_can.dbc b/generator/honda/honda_fit_hybrid_2018_can.dbc index 6b0a896b71..4ad9f2a062 100644 --- a/generator/honda/honda_fit_hybrid_2018_can.dbc +++ b/generator/honda/honda_fit_hybrid_2018_can.dbc @@ -26,8 +26,8 @@ BO_ 342 STEERING_SENSORS: 6 EPS SG_ CHECKSUM : 43|4@0+ (1,0) [0|3] "" EON BO_ 399 STEER_STATUS: 7 EPS - SG_ STEER_TORQUE_SENSOR : 7|16@0- (1,0) [-31000|31000] "tbd" EON - SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_SENSOR : 7|16@0- (-1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_MOTOR : 23|16@0- (-1,0) [-31000|31000] "tbd" EON SG_ STEER_STATUS : 39|4@0+ (1,0) [0|15] "" EON SG_ STEER_CONTROL_ACTIVE : 35|1@0+ (1,0) [0|1] "" EON SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON diff --git a/generator/honda/honda_odyssey_exl_2018.dbc b/generator/honda/honda_odyssey_exl_2018.dbc index fb54a29abc..8f04548910 100644 --- a/generator/honda/honda_odyssey_exl_2018.dbc +++ b/generator/honda/honda_odyssey_exl_2018.dbc @@ -18,8 +18,8 @@ BO_ 342 STEERING_SENSORS: 6 EPS SG_ CHECKSUM : 43|4@0+ (1,0) [0|3] "" EON BO_ 399 STEER_STATUS: 7 EPS - SG_ STEER_TORQUE_SENSOR : 7|16@0- (1,0) [-31000|31000] "tbd" EON - SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_SENSOR : 7|16@0- (-1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_MOTOR : 23|16@0- (-1,0) [-31000|31000] "tbd" EON SG_ STEER_STATUS : 39|4@0+ (1,0) [0|15] "" EON SG_ STEER_CONTROL_ACTIVE : 35|1@0+ (1,0) [0|1] "" EON SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON diff --git a/generator/honda/honda_odyssey_extreme_edition_2018_china_can.dbc b/generator/honda/honda_odyssey_extreme_edition_2018_china_can.dbc index 2d0d7e2b5d..7927f8c80f 100644 --- a/generator/honda/honda_odyssey_extreme_edition_2018_china_can.dbc +++ b/generator/honda/honda_odyssey_extreme_edition_2018_china_can.dbc @@ -11,8 +11,8 @@ BO_ 342 STEERING_SENSORS: 6 EPS SG_ STEER_ANGLE : 7|16@0- (-0.1,0) [-500|500] "deg" EON BO_ 399 STEER_STATUS: 7 EPS - SG_ STEER_TORQUE_SENSOR : 7|16@0- (1,0) [-2985|2985] "tbd" EON - SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_SENSOR : 7|16@0- (-1,0) [-2985|2985] "tbd" EON + SG_ STEER_TORQUE_MOTOR : 23|16@0- (-1,0) [-31000|31000] "tbd" EON SG_ CHECKSUM : 51|4@0+ (1,0) [0|15] "" EON SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON SG_ STEER_STATUS : 43|4@0+ (1,0) [0|15] "" EON diff --git a/generator/honda/honda_pilot_touring_2017_can.dbc b/generator/honda/honda_pilot_touring_2017_can.dbc index 779cd66f5b..ea9ec39644 100644 --- a/generator/honda/honda_pilot_touring_2017_can.dbc +++ b/generator/honda/honda_pilot_touring_2017_can.dbc @@ -26,8 +26,8 @@ BO_ 342 STEERING_SENSORS: 6 EPS SG_ CHECKSUM : 43|4@0+ (1,0) [0|3] "" EON BO_ 399 STEER_STATUS: 7 EPS - SG_ STEER_TORQUE_SENSOR : 7|16@0- (1,0) [-31000|31000] "tbd" EON - SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_SENSOR : 7|16@0- (-1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_MOTOR : 23|16@0- (-1,0) [-31000|31000] "tbd" EON SG_ STEER_STATUS : 39|4@0+ (1,0) [0|15] "" EON SG_ STEER_CONTROL_ACTIVE : 35|1@0+ (1,0) [0|1] "" EON SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON diff --git a/generator/honda/honda_ridgeline_black_edition_2017_can.dbc b/generator/honda/honda_ridgeline_black_edition_2017_can.dbc index d070d314d5..cec7a08e7d 100644 --- a/generator/honda/honda_ridgeline_black_edition_2017_can.dbc +++ b/generator/honda/honda_ridgeline_black_edition_2017_can.dbc @@ -21,8 +21,8 @@ BO_ 342 STEERING_SENSORS: 6 EPS SG_ CHECKSUM : 43|4@0+ (1,0) [0|3] "" EON BO_ 399 STEER_STATUS: 7 EPS - SG_ STEER_TORQUE_SENSOR : 7|16@0- (1,0) [-31000|31000] "tbd" EON - SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_SENSOR : 7|16@0- (-1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_MOTOR : 23|16@0- (-1,0) [-31000|31000] "tbd" EON SG_ STEER_STATUS : 39|4@0+ (1,0) [0|15] "" EON SG_ STEER_CONTROL_ACTIVE : 35|1@0+ (1,0) [0|1] "" EON SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON diff --git a/honda_accord_lx15t_2018_can_generated.dbc b/honda_accord_lx15t_2018_can_generated.dbc index 5b095ae793..0cf9ea5662 100644 --- a/honda_accord_lx15t_2018_can_generated.dbc +++ b/honda_accord_lx15t_2018_can_generated.dbc @@ -95,8 +95,8 @@ BO_ 380 POWERTRAIN_DATA: 8 PCM SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON BO_ 399 STEER_STATUS: 7 EPS - SG_ STEER_TORQUE_SENSOR : 7|16@0- (1,0) [-31000|31000] "tbd" EON - SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_SENSOR : 7|16@0- (-1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_MOTOR : 23|16@0- (-1,0) [-31000|31000] "tbd" EON SG_ STEER_STATUS : 39|4@0+ (1,0) [0|15] "" EON SG_ STEER_CONTROL_ACTIVE : 35|1@0+ (1,0) [0|1] "" EON SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON diff --git a/honda_accord_s2t_2018_can_generated.dbc b/honda_accord_s2t_2018_can_generated.dbc index 12a2b889fd..770cfdf1fd 100644 --- a/honda_accord_s2t_2018_can_generated.dbc +++ b/honda_accord_s2t_2018_can_generated.dbc @@ -95,8 +95,8 @@ BO_ 380 POWERTRAIN_DATA: 8 PCM SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON BO_ 399 STEER_STATUS: 7 EPS - SG_ STEER_TORQUE_SENSOR : 7|16@0- (1,0) [-31000|31000] "tbd" EON - SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_SENSOR : 7|16@0- (-1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_MOTOR : 23|16@0- (-1,0) [-31000|31000] "tbd" EON SG_ STEER_STATUS : 39|4@0+ (1,0) [0|15] "" EON SG_ STEER_CONTROL_ACTIVE : 35|1@0+ (1,0) [0|1] "" EON SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON diff --git a/honda_civic_hatchback_ex_2017_can_generated.dbc b/honda_civic_hatchback_ex_2017_can_generated.dbc index cfc8a6e48d..06c6edabdf 100644 --- a/honda_civic_hatchback_ex_2017_can_generated.dbc +++ b/honda_civic_hatchback_ex_2017_can_generated.dbc @@ -95,8 +95,8 @@ BO_ 380 POWERTRAIN_DATA: 8 PCM SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON BO_ 399 STEER_STATUS: 7 EPS - SG_ STEER_TORQUE_SENSOR : 7|16@0- (1,0) [-31000|31000] "tbd" EON - SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_SENSOR : 7|16@0- (-1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_MOTOR : 23|16@0- (-1,0) [-31000|31000] "tbd" EON SG_ STEER_STATUS : 39|4@0+ (1,0) [0|15] "" EON SG_ STEER_CONTROL_ACTIVE : 35|1@0+ (1,0) [0|1] "" EON SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON diff --git a/honda_civic_touring_2016_can_generated.dbc b/honda_civic_touring_2016_can_generated.dbc index 22f4a0b9fc..cb83511b3d 100644 --- a/honda_civic_touring_2016_can_generated.dbc +++ b/honda_civic_touring_2016_can_generated.dbc @@ -164,7 +164,7 @@ BO_ 780 ACC_HUD: 8 ADAS 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_OFF_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 @@ -174,10 +174,12 @@ BO_ 780 ACC_HUD: 8 ADAS 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_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" BDY SG_ SET_ME_X01_2 : 55|1@0+ (1,0) [0|1] "" BDY + SG_ IMPERIAL_UNIT : 54|1@0+ (1,0) [0|1] "" BDY + SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY + SG_ CHIME : 51|3@0+ (1,0) [0|1] "" BDY SG_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY + SG_ ICONS : 63|2@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 @@ -276,8 +278,8 @@ BO_ 330 STEERING_SENSORS: 8 EPS SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON BO_ 399 STEER_STATUS: 7 EPS - SG_ STEER_TORQUE_SENSOR : 7|16@0- (1,0) [-31000|31000] "tbd" EON - SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_SENSOR : 7|16@0- (-1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_MOTOR : 23|16@0- (-1,0) [-31000|31000] "tbd" EON SG_ STEER_STATUS : 39|4@0+ (1,0) [0|15] "" EON SG_ STEER_CONTROL_ACTIVE : 35|1@0+ (1,0) [0|1] "" EON SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON diff --git a/honda_clarity_hybrid_2018_can.dbc b/honda_clarity_hybrid_2018_can.dbc index 3d46f52cd5..dfd30ff79c 100644 --- a/honda_clarity_hybrid_2018_can.dbc +++ b/honda_clarity_hybrid_2018_can.dbc @@ -91,8 +91,8 @@ BO_ 380 POWERTRAIN_DATA2: 8 PCM 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_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 diff --git a/honda_crv_ex_2017_can_generated.dbc b/honda_crv_ex_2017_can_generated.dbc index f8b6846c53..7aa93a9635 100644 --- a/honda_crv_ex_2017_can_generated.dbc +++ b/honda_crv_ex_2017_can_generated.dbc @@ -95,8 +95,8 @@ BO_ 380 POWERTRAIN_DATA: 8 PCM SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON BO_ 399 STEER_STATUS: 7 EPS - SG_ STEER_TORQUE_SENSOR : 7|16@0- (1,0) [-31000|31000] "tbd" EON - SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_SENSOR : 7|16@0- (-1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_MOTOR : 23|16@0- (-1,0) [-31000|31000] "tbd" EON SG_ STEER_STATUS : 39|4@0+ (1,0) [0|15] "" EON SG_ STEER_CONTROL_ACTIVE : 35|1@0+ (1,0) [0|1] "" EON SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON diff --git a/honda_crv_hybrid_2019_can_generated.dbc b/honda_crv_hybrid_2019_can_generated.dbc index eba7e72a22..5d3e81ecbd 100644 --- a/honda_crv_hybrid_2019_can_generated.dbc +++ b/honda_crv_hybrid_2019_can_generated.dbc @@ -95,8 +95,8 @@ BO_ 380 POWERTRAIN_DATA: 8 PCM SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON BO_ 399 STEER_STATUS: 7 EPS - SG_ STEER_TORQUE_SENSOR : 7|16@0- (1,0) [-31000|31000] "tbd" EON - SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_SENSOR : 7|16@0- (-1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_MOTOR : 23|16@0- (-1,0) [-31000|31000] "tbd" EON SG_ STEER_STATUS : 39|4@0+ (1,0) [0|15] "" EON SG_ STEER_CONTROL_ACTIVE : 35|1@0+ (1,0) [0|1] "" EON SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON diff --git a/honda_crv_touring_2016_can_generated.dbc b/honda_crv_touring_2016_can_generated.dbc index 9b5075ba62..dca4299487 100644 --- a/honda_crv_touring_2016_can_generated.dbc +++ b/honda_crv_touring_2016_can_generated.dbc @@ -253,8 +253,8 @@ BO_ 342 STEERING_SENSORS: 6 EPS SG_ CHECKSUM : 43|4@0+ (1,0) [0|15] "" EON BO_ 399 STEER_STATUS: 6 EPS - SG_ STEER_TORQUE_SENSOR : 7|12@0- (1,0) [-2047.5|2047.5] "tbd" EON - SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_SENSOR : 7|12@0- (-1,0) [-2047.5|2047.5] "tbd" EON + SG_ STEER_TORQUE_MOTOR : 23|16@0- (-1,0) [-31000|31000] "tbd" EON SG_ STEER_CONTROL_ACTIVE : 36|1@0+ (1,0) [0|1] "" EON SG_ STEER_STATUS : 35|4@0+ (1,0) [0|15] "" EON SG_ COUNTER : 45|2@0+ (1,0) [0|3] "" EON diff --git a/honda_fit_ex_2018_can_generated.dbc b/honda_fit_ex_2018_can_generated.dbc index de9aca953f..df5fc95910 100644 --- a/honda_fit_ex_2018_can_generated.dbc +++ b/honda_fit_ex_2018_can_generated.dbc @@ -271,8 +271,8 @@ BO_ 342 STEERING_SENSORS: 6 EPS SG_ CHECKSUM : 43|4@0+ (1,0) [0|3] "" EON BO_ 399 STEER_STATUS: 7 EPS - SG_ STEER_TORQUE_SENSOR : 7|16@0- (1,0) [-31000|31000] "tbd" EON - SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_SENSOR : 7|16@0- (-1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_MOTOR : 23|16@0- (-1,0) [-31000|31000] "tbd" EON SG_ STEER_STATUS : 39|4@0+ (1,0) [0|15] "" EON SG_ STEER_CONTROL_ACTIVE : 35|1@0+ (1,0) [0|1] "" EON SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON diff --git a/honda_fit_hybrid_2018_can_generated.dbc b/honda_fit_hybrid_2018_can_generated.dbc index 8d3db09ec4..3490737c8e 100644 --- a/honda_fit_hybrid_2018_can_generated.dbc +++ b/honda_fit_hybrid_2018_can_generated.dbc @@ -265,8 +265,8 @@ BO_ 342 STEERING_SENSORS: 6 EPS SG_ CHECKSUM : 43|4@0+ (1,0) [0|3] "" EON BO_ 399 STEER_STATUS: 7 EPS - SG_ STEER_TORQUE_SENSOR : 7|16@0- (1,0) [-31000|31000] "tbd" EON - SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_SENSOR : 7|16@0- (-1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_MOTOR : 23|16@0- (-1,0) [-31000|31000] "tbd" EON SG_ STEER_STATUS : 39|4@0+ (1,0) [0|15] "" EON SG_ STEER_CONTROL_ACTIVE : 35|1@0+ (1,0) [0|1] "" EON SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON diff --git a/honda_insight_ex_2019_can_generated.dbc b/honda_insight_ex_2019_can_generated.dbc index 92fc0b50ac..890ae8a2e6 100644 --- a/honda_insight_ex_2019_can_generated.dbc +++ b/honda_insight_ex_2019_can_generated.dbc @@ -95,8 +95,8 @@ BO_ 380 POWERTRAIN_DATA: 8 PCM SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" EON BO_ 399 STEER_STATUS: 7 EPS - SG_ STEER_TORQUE_SENSOR : 7|16@0- (1,0) [-31000|31000] "tbd" EON - SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_SENSOR : 7|16@0- (-1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_MOTOR : 23|16@0- (-1,0) [-31000|31000] "tbd" EON SG_ STEER_STATUS : 39|4@0+ (1,0) [0|15] "" EON SG_ STEER_CONTROL_ACTIVE : 35|1@0+ (1,0) [0|1] "" EON SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON diff --git a/honda_odyssey_exl_2018_generated.dbc b/honda_odyssey_exl_2018_generated.dbc index 2899dba670..ae0394d5a6 100644 --- a/honda_odyssey_exl_2018_generated.dbc +++ b/honda_odyssey_exl_2018_generated.dbc @@ -263,8 +263,8 @@ BO_ 342 STEERING_SENSORS: 6 EPS SG_ CHECKSUM : 43|4@0+ (1,0) [0|3] "" EON BO_ 399 STEER_STATUS: 7 EPS - SG_ STEER_TORQUE_SENSOR : 7|16@0- (1,0) [-31000|31000] "tbd" EON - SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_SENSOR : 7|16@0- (-1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_MOTOR : 23|16@0- (-1,0) [-31000|31000] "tbd" EON SG_ STEER_STATUS : 39|4@0+ (1,0) [0|15] "" EON SG_ STEER_CONTROL_ACTIVE : 35|1@0+ (1,0) [0|1] "" EON SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON diff --git a/honda_odyssey_extreme_edition_2018_china_can_generated.dbc b/honda_odyssey_extreme_edition_2018_china_can_generated.dbc index f8565c03b0..01b2b6f468 100644 --- a/honda_odyssey_extreme_edition_2018_china_can_generated.dbc +++ b/honda_odyssey_extreme_edition_2018_china_can_generated.dbc @@ -256,8 +256,8 @@ BO_ 342 STEERING_SENSORS: 6 EPS SG_ STEER_ANGLE : 7|16@0- (-0.1,0) [-500|500] "deg" EON BO_ 399 STEER_STATUS: 7 EPS - SG_ STEER_TORQUE_SENSOR : 7|16@0- (1,0) [-2985|2985] "tbd" EON - SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_SENSOR : 7|16@0- (-1,0) [-2985|2985] "tbd" EON + SG_ STEER_TORQUE_MOTOR : 23|16@0- (-1,0) [-31000|31000] "tbd" EON SG_ CHECKSUM : 51|4@0+ (1,0) [0|15] "" EON SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON SG_ STEER_STATUS : 43|4@0+ (1,0) [0|15] "" EON diff --git a/honda_pilot_touring_2017_can_generated.dbc b/honda_pilot_touring_2017_can_generated.dbc index 223aa1b27a..fbd8326096 100644 --- a/honda_pilot_touring_2017_can_generated.dbc +++ b/honda_pilot_touring_2017_can_generated.dbc @@ -271,8 +271,8 @@ BO_ 342 STEERING_SENSORS: 6 EPS SG_ CHECKSUM : 43|4@0+ (1,0) [0|3] "" EON BO_ 399 STEER_STATUS: 7 EPS - SG_ STEER_TORQUE_SENSOR : 7|16@0- (1,0) [-31000|31000] "tbd" EON - SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_SENSOR : 7|16@0- (-1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_MOTOR : 23|16@0- (-1,0) [-31000|31000] "tbd" EON SG_ STEER_STATUS : 39|4@0+ (1,0) [0|15] "" EON SG_ STEER_CONTROL_ACTIVE : 35|1@0+ (1,0) [0|1] "" EON SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON diff --git a/honda_ridgeline_black_edition_2017_can_generated.dbc b/honda_ridgeline_black_edition_2017_can_generated.dbc index 8572b0b5ed..ebf8e3098e 100644 --- a/honda_ridgeline_black_edition_2017_can_generated.dbc +++ b/honda_ridgeline_black_edition_2017_can_generated.dbc @@ -266,8 +266,8 @@ BO_ 342 STEERING_SENSORS: 6 EPS SG_ CHECKSUM : 43|4@0+ (1,0) [0|3] "" EON BO_ 399 STEER_STATUS: 7 EPS - SG_ STEER_TORQUE_SENSOR : 7|16@0- (1,0) [-31000|31000] "tbd" EON - SG_ STEER_TORQUE_MOTOR : 23|16@0- (1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_SENSOR : 7|16@0- (-1,0) [-31000|31000] "tbd" EON + SG_ STEER_TORQUE_MOTOR : 23|16@0- (-1,0) [-31000|31000] "tbd" EON SG_ STEER_STATUS : 39|4@0+ (1,0) [0|15] "" EON SG_ STEER_CONTROL_ACTIVE : 35|1@0+ (1,0) [0|1] "" EON SG_ COUNTER : 53|2@0+ (1,0) [0|3] "" EON diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000..c1ac27ec92 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,7 @@ +Cython==0.29.14 +flake8==3.7.9 +Jinja2==2.10.3 +pycapnp==0.6.4 +pylint==2.4.3 +pyyaml==5.1.2 +scons==3.1.1 diff --git a/subaru_outback_2015_eyesight.dbc b/subaru_outback_2015_eyesight.dbc index 2f79655850..dd1d5422c5 100644 --- a/subaru_outback_2015_eyesight.dbc +++ b/subaru_outback_2015_eyesight.dbc @@ -33,47 +33,47 @@ NS_ : BS_: -BU_: XXX +BU_: XXX 0 BO_ 2 Steering: 8 XXX - SG_ NEW_SIGNAL_1 : 31|4@0- (1,0) [0|65535] "" XXX - SG_ Counter : 25|3@1+ (1,0) [0|15] "" XXX - SG_ Checksum : 32|8@1+ (1,0) [0|255] "" XXX - SG_ NEW_SIGNAL_2 : 22|3@0+ (1,0) [0|7] "" XXX - SG_ NEW_SIGNAL_6 : 24|1@1+ (1,0) [0|3] "" XXX SG_ Steering_Angle : 7|16@0- (0.1,0) [-500|500] "degree" XXX + SG_ NEW_SIGNAL_6 : 24|1@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_2 : 22|3@0+ (1,0) [0|7] "" XXX + SG_ Counter : 27|3@0+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_1 : 31|4@0- (1,0) [0|65535] "" XXX + SG_ Checksum : 39|8@0+ (1,0) [0|255] "" XXX BO_ 208 G_Sensor: 8 XXX SG_ NEW_SIGNAL_3 : 32|8@1+ (1,0) [0|255] "" XXX - SG_ Steering_Angle : 0|16@1- (1,0) [0|65535] "" XXX - SG_ NEW_SIGNAL_1 : 47|8@0+ (1,0) [0|255] "" XXX SG_ _Latitudinal : 16|16@1- (0.0035,1) [0|65535] "" XXX SG_ _Longitudinal : 48|16@1- (0.000035,0) [0|255] "" XXX + SG_ Steering_Angle : 0|16@1- (1,0) [0|65535] "" XXX + SG_ NEW_SIGNAL_1 : 40|8@1+ (1,0) [0|255] "" XXX BO_ 209 Brake_Pedal: 8 XXX SG_ NEW_SIGNAL_1 : 26|1@1+ (1,0) [0|3] "" XXX - SG_ Brake_Pedal : 23|8@0+ (1,0) [0|255] "" XXX SG_ NEW_SIGNAL_2 : 31|1@1+ (1,0) [0|255] "" XXX + SG_ Brake_Pedal : 16|8@1+ (1,0) [0|255] "" XXX SG_ Speed : 0|16@1+ (0.05625,0) [0|255] "KPH" XXX BO_ 210 Brake_2: 8 XXX - SG_ NEW_SIGNAL_1 : 46|1@0+ (1,0) [0|4294967295] "" XXX - SG_ NEW_SIGNAL_2 : 39|3@0+ (1,0) [0|7] "" XXX SG_ Right_Brake : 48|8@1+ (1,0) [0|255] "" XXX - SG_ Left_Brake : 63|8@0+ (1,0) [0|255] "" XXX SG_ Brake_Light : 35|1@1+ (1,0) [0|15] "" XXX SG_ Brake_Related : 36|1@1+ (1,0) [0|255] "" XXX + SG_ Left_Brake : 56|8@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_1 : 46|1@1+ (1,0) [0|4294967295] "" XXX + SG_ NEW_SIGNAL_2 : 37|3@1+ (1,0) [0|7] "" XXX BO_ 211 Brake_Type: 8 XXX - SG_ NEW_SIGNAL_4 : 28|4@1+ (1,0) [0|15] "" XXX - SG_ NEW_SIGNAL_3 : 7|1@0+ (1,0) [0|4294967295] "" XXX + SG_ NEW_SIGNAL_3 : 7|1@1+ (1,0) [0|4294967295] "" XXX SG_ NEW_SIGNAL_2 : 16|4@1+ (1,0) [0|15] "" XXX - SG_ Speed_Counter : 39|8@0+ (1,0) [0|15] "" XXX - SG_ Counter : 55|8@0+ (1,0) [0|255] "" XXX - SG_ Brake_Light : 21|1@0+ (1,0) [0|3] "" XXX - SG_ Brake_Cruise_On : 42|1@0+ (1,0) [0|3] "" XXX - SG_ Brake_Pedal_On : 46|1@0+ (1,0) [0|3] "" XXX + SG_ Brake_Light : 21|1@1+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_4 : 28|4@1+ (1,0) [0|15] "" XXX + SG_ Speed_Counter : 32|8@1+ (1,0) [0|15] "" XXX + SG_ Brake_Cruise_On : 42|1@1+ (1,0) [0|3] "" XXX + SG_ Brake_Pedal_On : 46|1@1+ (1,0) [0|3] "" XXX + SG_ Counter : 48|8@1+ (1,0) [0|255] "" XXX BO_ 212 Wheel_Speeds: 8 XXX SG_ FL : 0|16@1+ (0.0592,0) [2|255] "KPH" XXX @@ -85,72 +85,71 @@ BO_ 320 Throttle: 8 XXX SG_ Off_Throttle_2 : 56|1@1+ (1,0) [0|3] "" XXX SG_ Throttle_Combo : 40|8@1+ (1,0) [0|255] "" XXX SG_ Engine_RPM : 16|14@1+ (1,0) [0|15] "" XXX - SG_ Off_Throttle : 30|1@0+ (1,0) [0|3] "" XXX - SG_ Throttle_Cruise : 39|8@0+ (1,0) [0|255] "" XXX - SG_ Throttle_Body_ : 55|8@0+ (1,0) [0|255] "" XXX - SG_ NEW_SIGNAL_3 : 63|1@0+ (1,0) [0|15] "" XXX - SG_ Not_Full_Throttle : 14|1@0+ (1,0) [0|15] "" XXX - SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_3 : 63|1@1+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_1 : 61|1@1+ (1,0) [0|3] "" XXX + SG_ Throttle_Body_ : 48|8@1+ (1,0) [0|255] "" XXX + SG_ Throttle_Cruise : 32|8@1+ (1,0) [0|255] "" XXX + SG_ Off_Throttle : 30|1@1+ (1,0) [0|3] "" XXX SG_ Throttle_Pedal : 0|8@1+ (0.392157,0) [0|255] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + SG_ Not_Full_Throttle : 14|1@1+ (1,0) [0|15] "" XXX -BO_ 321 undefined: 8 XXX +BO_ 321 Engine: 8 XXX SG_ NEW_SIGNAL_7 : 59|2@1+ (1,0) [0|63] "" XXX - SG_ NEW_SIGNAL_6 : 46|1@0+ (1,0) [0|3] "" XXX SG_ NEW_SIGNAL_2 : 47|1@1+ (1,0) [0|15] "" XXX SG_ NEW_SIGNAL_5 : 48|4@1+ (1,0) [0|15] "" XXX - SG_ NEW_SIGNAL_3 : 54|2@0+ (1,0) [0|255] "" XXX - SG_ NEW_SIGNAL_8 : 31|4@0+ (1,0) [0|15] "" XXX + SG_ Wheel_Torque : 16|12@1+ (1,0) [0|255] "" XXX SG_ Engine_RPM : 32|12@1+ (1,0) [0|8191] "" XXX + SG_ NEW_SIGNAL_3 : 53|2@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_6 : 46|1@1+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_8 : 28|4@1+ (1,0) [0|15] "" XXX + SG_ Engine_Stop : 15|1@1+ (1,0) [0|3] "" XXX SG_ Engine_Torque : 0|15@1+ (1,0) [0|255] "" XXX - SG_ Wheel_Torque : 16|12@1+ (1,0) [0|255] "" XXX - SG_ Engine_Stop : 15|1@0+ (1,0) [0|3] "" XXX BO_ 324 CruiseControl: 8 XXX - SG_ Cruise_On : 48|1@0+ (1,0) [0|3] "" XXX SG_ OnOffButton : 2|1@1+ (1,0) [0|3] "" XXX - SG_ SET_BUTTON : 3|1@0+ (1,0) [0|3] "" XXX - SG_ RES_BUTTON : 4|1@0+ (1,0) [0|3] "" XXX - SG_ NEW_SIGNAL_6 : 50|1@0+ (1,0) [0|3] "" XXX - SG_ NEW_SIGNAL_4 : 28|5@0+ (1,0) [0|16777215] "" XXX + SG_ SET_BUTTON : 3|1@1+ (1,0) [0|3] "" XXX + SG_ RES_BUTTON : 4|1@1+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_2 : 8|1@1+ (1,0) [0|255] "" XXX + SG_ Button : 13|1@1+ (1,0) [0|3] "" XXX SG_ NEW_SIGNAL_9 : 15|1@1+ (1,0) [0|127] "" XXX - SG_ NEW_SIGNAL_2 : 8|1@0+ (1,0) [0|255] "" XXX - SG_ Cruise_Activated : 49|1@0+ (1,0) [0|7] "" XXX - SG_ Brake_Pedal_On : 51|1@0+ (1,0) [0|3] "" XXX - SG_ NEW_SIGNAL_1 : 23|8@0+ (1,-124) [0|255] "" XXX - SG_ Button : 13|1@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_1 : 16|8@1+ (1,-124) [0|255] "" XXX + SG_ NEW_SIGNAL_4 : 24|5@1+ (1,0) [0|16777215] "" XXX + SG_ Cruise_On : 48|1@1+ (1,0) [0|3] "" XXX + SG_ Cruise_Activated : 49|1@1+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_6 : 50|1@1+ (1,0) [0|3] "" XXX + SG_ Brake_Pedal_On : 51|1@1+ (1,0) [0|3] "" XXX BO_ 328 Transmission: 8 XXX - SG_ Counter : 11|4@0+ (1,0) [0|255] "" XXX - SG_ NEW_SIGNAL_7 : 63|1@0+ (1,0) [0|3] "" XXX - SG_ NEW_SIGNAL_4 : 15|4@0+ (1,0) [0|15] "" XXX SG_ Paddle_Shift : 60|2@1+ (1,0) [0|255] "" XXX - SG_ NEW_SIGNAL_1 : 31|1@0+ (1,0) [0|3] "" XXX - SG_ Transmission_Engine : 16|15@1+ (1,0) [0|65535] "" XXX - SG_ NEW_SIGNAL_5 : 43|1@0+ (1,0) [0|65535] "" XXX SG_ Gear : 48|4@1+ (1,0) [0|15] "" XXX SG_ Gear_2 : 52|4@1+ (1,0) [0|15] "" XXX SG_ Manual_Gear : 4|4@1+ (1,0) [0|255] "" XXX + SG_ Transmission_Engine : 16|15@1+ (1,0) [0|65535] "" XXX + SG_ NEW_SIGNAL_7 : 63|1@1+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_5 : 43|1@1+ (1,0) [0|65535] "" XXX + SG_ NEW_SIGNAL_1 : 31|1@1+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_4 : 12|4@1+ (1,0) [0|15] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|255] "" XXX BO_ 329 CVT_Ratio: 8 XXX - SG_ NEW_SIGNAL_2 : 31|8@0+ (1,0) [0|255] "" XXX - SG_ NEW_SIGNAL_3 : 40|8@1+ (1,0) [0|255] "" XXX SG_ NEW_SIGNAL_4 : 0|8@1+ (1,0) [0|255] "" XXX - SG_ NEW_SIGNAL_5 : 11|4@0+ (1,0) [0|65535] "" XXX - SG_ NEW_SIGNAL_1 : 39|8@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_5 : 8|4@1+ (1,0) [0|65535] "" XXX + SG_ NEW_SIGNAL_2 : 24|8@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_1 : 32|8@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_3 : 40|8@1+ (1,0) [0|255] "" XXX BO_ 336 Brake_Pressure: 8 XXX SG_ Brake_Pressure_Right : 0|8@1+ (1,0) [0|15] "" XXX - SG_ Brake_Pressure_Left : 15|8@0+ (1,0) [0|255] "" XXX + SG_ Brake_Pressure_Left : 8|8@1+ (1,0) [0|255] "" XXX BO_ 338 Stalk: 8 XXX - SG_ Wiper : 62|1@0+ (1,0) [0|3] "" XXX - SG_ brake_light : 52|1@0+ (1,0) [0|3] "" XXX - SG_ Headlights : 59|1@0+ (1,0) [0|3] "" XXX SG_ Runlights : 58|1@1+ (1,0) [0|3] "" XXX - SG_ Highbeam : 60|1@0+ (1,0) [0|3] "" XXX - SG_ Counter : 15|4@0+ (1,0) [0|15] "" XXX - -BO_ 342 NEW_MSG_2: 8 XXX + SG_ Wiper : 62|1@1+ (1,0) [0|3] "" XXX + SG_ Highbeam : 60|1@1+ (1,0) [0|3] "" XXX + SG_ Headlights : 59|1@1+ (1,0) [0|3] "" XXX + SG_ brake_light : 52|1@1+ (1,0) [0|3] "" XXX + SG_ Counter : 12|4@1+ (1,0) [0|15] "" XXX BO_ 346 Counter_3: 8 XXX SG_ Counter : 0|4@1+ (1,0) [0|15] "" XXX @@ -160,36 +159,40 @@ BO_ 346 Counter_3: 8 XXX BO_ 352 ES_Brake: 8 XXX SG_ Counter : 48|3@1+ (1,0) [0|7] "" XXX SG_ Checksum : 56|8@1+ (1,0) [0|7] "" XXX - SG_ Brake_On : 22|1@0+ (1,0) [0|3] "" XXX - SG_ Brake_Light : 20|1@0+ (1,0) [0|2047] "" XXX - SG_ Cruise_Activated : 23|1@0+ (1,0) [0|3] "" XXX SG_ Brake_Pressure : 0|16@1+ (1,0) [0|255] "" XXX - SG_ ES_Error : 21|1@0+ (1,0) [0|7] "" XXX + SG_ Cruise_Activated : 23|1@1+ (1,0) [0|3] "" XXX + SG_ Brake_On : 22|1@1+ (1,0) [0|3] "" XXX + SG_ ES_Error : 21|1@1+ (1,0) [0|7] "" XXX + SG_ Brake_Light : 20|1@1+ (1,0) [0|2047] "" XXX BO_ 353 ES_CruiseThrottle: 8 XXX - SG_ Throttle_Cruise : 0|12@1+ (1,0) [0|255] "" XXX - SG_ Counter_1 : 46|3@0+ (1,0) [0|15] "" XXX - SG_ Wheel_stop : 22|1@0+ (1,0) [0|3] "" XXX - SG_ CloseDistance : 24|8@1+ (1,0) [0|255] "" XXX - SG_ Unknown : 18|1@1+ (1,0) [0|7] "" XXX - SG_ Button_Speed_Down : 49|1@1+ (1,0) [0|3] "" XXX - SG_ Button_Resume : 50|1@1+ (1,0) [0|15] "" XXX - SG_ NEW_SIGNAL_3_Blank : 15|4@0+ (1,0) [0|15] "" XXX - SG_ NEW_SIGNAL_2_Blank : 48|1@1+ (1,0) [0|3] "" XXX SG_ Checksum : 56|8@1+ (1,0) [0|15] "" XXX - SG_ NEW_SIGNAL_9 : 17|1@1+ (1,0) [0|3] "" XXX - SG_ Cruise_Activatedish : 16|1@1+ (1,0) [0|7] "" XXX - SG_ NEW_SIGNAL_6_Blank : 23|1@0+ (1,0) [0|7] "" XXX - SG_ DistanceSwap : 21|1@0+ (1,0) [0|3] "" XXX - SG_ Brake_On : 20|1@0+ (1,0) [0|7] "" XXX + SG_ Button : 48|3@1+ (1,0) [0|3] "" XXX SG_ ES_Error : 42|1@1+ (1,0) [0|3] "" XXX + SG_ Standstill_2 : 41|1@1+ (1,0) [0|3] "" XXX + SG_ Standstill : 22|1@1+ (1,0) [0|3] "" XXX + SG_ Unknown : 18|1@1+ (1,0) [0|7] "" XXX + SG_ Brake_On : 20|1@1+ (1,0) [0|7] "" XXX + SG_ DistanceSwap : 21|1@1+ (1,0) [0|3] "" XXX + SG_ Counter : 44|3@1+ (1,0) [0|15] "" XXX + SG_ SET_0_1 : 32|9@1+ (1,0) [0|255] "" XXX + SG_ CloseDistance : 24|8@1+ (0.0196,0) [0|255] "m" XXX + SG_ SET_0_2 : 51|5@1+ (1,0) [0|31] "" XXX + SG_ SET_0_3 : 47|1@1+ (1,0) [0|3] "" XXX + SG_ SET_0_4 : 43|1@1+ (1,0) [0|3] "" XXX + SG_ SET_1 : 23|1@1+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_1 : 19|1@1+ (1,0) [0|1] "" XXX + SG_ Throttle_Cruise : 0|12@1+ (1,0) [0|255] "" XXX + SG_ SET_2 : 12|4@1+ (1,0) [0|15] "" XXX + SG_ Cruise_Activatedish : 16|1@1+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_9 : 17|1@1+ (1,0) [0|3] "" XXX BO_ 354 ES_RPM: 8 XXX SG_ Counter : 48|3@1+ (1,0) [0|7] "" XXX - SG_ Cruise_Activated : 9|1@0+ (1,0) [0|3] "" XXX - SG_ Checksum : 39|8@0+ (1,0) [0|65535] "" XXX SG_ RPM : 16|16@1+ (1,0) [0|255] "" XXX SG_ Brake : 8|1@1+ (1,0) [0|7] "" XXX + SG_ Cruise_Activated : 9|1@1+ (1,0) [0|3] "" XXX + SG_ Checksum : 32|8@1+ (1,0) [0|65535] "" XXX BO_ 356 ES_LKAS: 8 XXX SG_ Checksum : 56|8@1+ (1,0) [0|255] "" XXX @@ -198,39 +201,39 @@ BO_ 356 ES_LKAS: 8 XXX SG_ LKAS_Command : 8|13@1- (-1,0) [-4096|4096] "" XXX BO_ 358 ES_DashStatus: 8 XXX - SG_ Counter : 39|3@0+ (1,0) [0|7] "" XXX - SG_ Obstacle_Distance : 48|4@1+ (1,0) [0|15] "" XXX - SG_ Cruise_Off : 22|1@0+ (1,0) [0|3] "" XXX - SG_ Car_Follow : 46|1@1+ (1,0) [0|255] "" XXX - SG_ Driver_Input : 20|1@0+ (1,0) [0|15] "" XXX + SG_ Not_Ready_Startup : 0|3@1+ (1,0) [0|7] "" XXX + SG_ 3SecondDisengage : 12|2@1+ (1,0) [0|3] "" XXX + SG_ Disengage_Alert : 14|2@1+ (1,0) [0|3] "" XXX + SG_ Cruise_On : 16|1@1+ (1,0) [0|7] "" XXX + SG_ Cruise_Activated : 17|1@1+ (1,0) [0|3] "" XXX SG_ WHEELS_MOVING_2015 : 19|1@1+ (1,0) [0|3] "" XXX - SG_ Untitled_Blank : 18|1@0+ (1,0) [0|3] "" XXX - SG_ NEW_SIGNAL_6_Blank : 21|1@0+ (1,0) [0|3] "" XXX - SG_ NEW_SIGNAL_5_Blank : 33|1@1+ (1,0) [0|3] "" XXX - SG_ NEW_SIGNAL_4_Blank : 34|1@1+ (1,0) [0|7] "" XXX - SG_ NEW_SIGNAL_1 : 35|1@0+ (1,0) [0|31] "" XXX - SG_ Steep_Hill_Disengage : 44|1@0+ (1,0) [0|3] "" XXX + SG_ Driver_Input : 20|1@1+ (1,0) [0|15] "" XXX SG_ ES_Error : 32|1@1+ (1,0) [0|3] "" XXX - SG_ Cruise_Activated : 17|1@1+ (1,0) [0|3] "" XXX - SG_ Cruise_On : 16|1@1+ (1,0) [0|7] "" XXX - SG_ Disengage_Alert : 15|2@0+ (1,0) [0|3] "" XXX - SG_ 3SecondDisengage : 13|2@0+ (1,0) [0|3] "" XXX - SG_ Not_Ready_Startup : 0|3@1+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_5_Blank : 33|1@1+ (1,0) [0|3] "" XXX + SG_ Cruise_On_2 : 34|1@1+ (1,0) [0|7] "" XXX + SG_ NEW_SIGNAL_1 : 35|1@1+ (1,0) [0|31] "" XXX + SG_ Counter : 37|3@1+ (1,0) [0|7] "" XXX + SG_ Steep_Hill_Disengage : 44|1@1+ (1,0) [0|3] "" XXX + SG_ Lead_Car : 46|1@1+ (1,0) [0|255] "" XXX SG_ Cruise_Set_Speed : 24|8@1+ (1,0) [0|255] "" XXX + SG_ Distance_Bars : 21|3@1+ (1,0) [0|3] "" XXX + SG_ Untitled_Blank_2 : 18|1@1+ (1,0) [0|3] "" XXX + SG_ Obstacle_Distance : 48|4@1+ (5,0) [0|15] "m" XXX BO_ 359 ES_LDW: 8 XXX - SG_ All_depart_2015 : 0|1@1+ (1,0) [0|255] "" XXX - SG_ LKAS_Inactive_2017 : 36|1@1+ (1,0) [0|3] "" XXX - SG_ LKAS_Steer_Active_2017 : 37|1@0+ (1,0) [0|3] "" XXX - SG_ Right_Line_2017 : 24|1@1+ (1,0) [0|7] "" XXX SG_ Left_Line_2017 : 25|1@1+ (1,0) [0|3] "" XXX - SG_ Sig2All_Depart : 28|1@0+ (1,0) [0|3] "" XXX - SG_ Sig1All_Depart : 31|1@0+ (1,0) [0|15] "" XXX SG_ Sig1Right_Depart : 48|1@1+ (1,0) [0|3] "" XXX - SG_ Sig1Right_Depart_Front : 49|1@1+ (1,0) [0|3] "" XXX SG_ Sig2Right_Depart : 50|1@1+ (1,0) [0|7] "" XXX - SG_ Left_Depart_Front : 51|1@0+ (1,0) [0|3] "" XXX - SG_ Sig3All_Depart : 52|1@0+ (1,0) [0|3] "" XXX + SG_ LKAS_Inactive_2017 : 36|1@1+ (1,0) [0|3] "" XXX + SG_ Sig1Right_Depart_Front : 49|1@1+ (1,0) [0|3] "" XXX + SG_ Sig3All_Depart : 52|1@1+ (1,0) [0|3] "" XXX + SG_ Left_Depart_Front : 51|1@1+ (1,0) [0|3] "" XXX + SG_ Alerts : 48|5@1+ (1,0) [0|3] "" XXX + SG_ LKAS_Active : 37|1@1+ (1,0) [0|3] "" XXX + SG_ Sig1All_Depart : 31|1@1+ (1,0) [0|15] "" XXX + SG_ Sig2All_Depart : 28|1@1+ (1,0) [0|3] "" XXX + SG_ Right_Line_2017 : 24|1@1+ (1,0) [0|7] "" XXX + SG_ All_depart_2015 : 0|1@1+ (1,0) [0|255] "" XXX BO_ 392 Counter_0: 8 XXX SG_ Counter : 16|4@1+ (1,0) [0|15] "" XXX @@ -238,62 +241,56 @@ BO_ 392 Counter_0: 8 XXX BO_ 554 NEW_MSG_3: 8 XXX SG_ Counter : 0|4@1+ (1,0) [0|255] "" XXX -BO_ 604 undefined: 8 XXX - BO_ 640 NEW_MSG_10: 8 XXX - SG_ NEW_SIGNAL_2 : 24|8@1+ (1,0) [0|255] "" XXX - SG_ NEW_SIGNAL_4 : 54|2@0+ (1,0) [0|15] "" XXX - SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX - SG_ NEW_SIGNAL_3 : 34|2@0+ (1,0) [0|63] "" XXX - SG_ NEW_SIGNAL_1 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ NEW_SIGNAL_5 : 39|1@0+ (1,0) [0|3] "" XXX SG_ NEW_SIGNAL_6 : 0|1@1+ (1,0) [0|7] "" XXX - SG_ NEW_SIGNAL_7 : 38|1@0+ (1,0) [0|3] "" XXX + SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX + SG_ NEW_SIGNAL_2 : 24|8@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_3 : 33|2@1+ (1,0) [0|63] "" XXX + SG_ NEW_SIGNAL_7 : 38|1@1+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_5 : 39|1@1+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_1 : 40|8@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_4 : 53|2@1+ (1,0) [0|15] "" XXX BO_ 642 Dashlights: 8 XXX SG_ NEW_SIGNAL_2 : 32|1@1+ (1,0) [0|15] "" XXX - SG_ Counter : 15|4@0+ (1,0) [0|15] "" XXX - SG_ NEW_SIGNAL_1 : 0|12@1+ (1,0) [0|255] "" XXX SG_ NEW_SIGNAL_3 : 34|2@1+ (1,0) [0|3] "" XXX - SG_ LEFT_BLINKER : 44|1@0+ (1,0) [0|3] "" XXX - SG_ RIGHT_BLINKER : 45|1@0+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_1 : 0|12@1+ (1,0) [0|255] "" XXX + SG_ Counter : 12|4@1+ (1,0) [0|15] "" XXX + SG_ RIGHT_BLINKER : 45|1@1+ (1,0) [0|3] "" XXX + SG_ LEFT_BLINKER : 44|1@1+ (1,0) [0|3] "" XXX SG_ SEATBELT_FL : 40|1@1+ (1,0) [0|3] "" XXX BO_ 644 NEW_MSG_8: 8 XXX SG_ Counter : 8|4@1+ (1,0) [0|15] "" XXX -BO_ 805 undefined: 8 XXX - BO_ 880 Steer_Torque_2: 8 XXX + SG_ Steering_Voltage_Flat : 0|8@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_1 : 8|1@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_2 : 30|1@1+ (1,0) [0|3] "" XXX + SG_ Steer_Torque_Sensor : 32|8@1- (-1,0) [0|255] "" XXX SG_ Counter : 40|4@1+ (1,0) [0|15] "" XXX SG_ NEW_SIGNAL_3 : 48|4@1- (1,0) [0|15] "" XXX - SG_ Steering_Voltage_Flat : 7|8@0+ (1,0) [0|255] "" XXX - SG_ NEW_SIGNAL_1 : 8|1@0+ (1,0) [0|255] "" XXX - SG_ NEW_SIGNAL_2 : 30|1@0+ (1,0) [0|3] "" XXX - SG_ NEW_SIGNAL_4_2017 : 52|1@0+ (1,0) [0|3] "" XXX - SG_ NEW_SIGNAL_5_2017 : 54|1@0+ (1,0) [0|3] "" XXX - SG_ Steer_Torque_Sensor : 32|8@1- (-1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_4_2017 : 52|1@1+ (1,0) [0|3] "" XXX + SG_ NEW_SIGNAL_5_2017 : 54|1@1+ (1,0) [0|3] "" XXX BO_ 881 Steering_Torque: 8 XXX SG_ Steering_Motor_Flat : 0|10@1+ (32,0) [0|16500] "" XXX SG_ Steer_Torque_Output : 16|11@1- (-32,0) [-16500|16500] "" XXX - SG_ Steer_Torque_Sensor : 29|11@1- (8,0) [-8500|-8500] "" XXX - SG_ Steering_Angle : 40|16@1- (-0.026,0) [-600|600] "" XXX SG_ LKA_Lockout : 27|1@1+ (1,0) [0|1] "" XXX + SG_ Steer_Torque_Sensor : 29|11@1- (8,0) [-8500|-8500] "" XXX + SG_ Steering_Angle : 40|16@1- (-0.033,0) [-600|600] "" XXX BO_ 882 Counter: 8 XXX - SG_ Counter : 15|4@0+ (1,0) [0|31] "" XXX SG_ Something : 16|2@1+ (1,0) [0|255] "" XXX + SG_ Counter : 12|4@1+ (1,0) [0|31] "" XXX BO_ 884 BodyInfo: 8 XXX - SG_ DOOR_OPEN_FR : 24|1@0+ (1,0) [0|1] "" XXX - SG_ DOOR_OPEN_FL : 25|1@0+ (1,0) [0|1] "" XXX - SG_ DOOR_OPEN_RL : 26|1@0+ (1,0) [0|1] "" XXX - SG_ DOOR_OPEN_RR : 27|1@0+ (1,0) [0|1] "" XXX - SG_ DOOR_OPEN_Hatch : 28|1@0+ (1,0) [0|1] "" XXX - SG_ _UNKNOWN : 2|3@0+ (1,0) [0|1] "" XXX - -BO_ 886 undefined: 8 XXX + SG_ DOOR_OPEN_Hatch : 28|1@1+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_RR : 27|1@1+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_RL : 26|1@1+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_FL : 25|1@1+ (1,0) [0|1] "" XXX + SG_ DOOR_OPEN_FR : 24|1@1+ (1,0) [0|1] "" XXX + SG_ _UNKNOWN : 0|3@1+ (1,0) [0|1] "" XXX BO_ 864 Engine_Temp: 8 XXX SG_ NEW_SIGNAL_1 : 32|8@1+ (1,0) [0|255] "" XXX @@ -309,22 +306,22 @@ BO_ 865 NEW_MSG_16: 8 XXX SG_ NEW_SIGNAL_2 : 12|1@1+ (1,0) [0|255] "" XXX BO_ 866 Fuel__: 8 XXX - SG_ NEW_SIGNAL_2 : 55|8@0+ (1,0) [0|16777215] "" XXX - SG_ NEW_SIGNAL_3 : 35|4@0+ (1,0) [0|255] "" XXX - SG_ NEW_SIGNAL_4 : 47|8@0+ (1,0) [0|1] "" XXX SG_ NEW_SIGNAL_1 : 0|16@1+ (1,0) [0|255] "" XXX - SG_ NEW_SIGNAL_5 : 24|1@0+ (1,0) [0|32767] "" XXX + SG_ NEW_SIGNAL_5 : 24|1@1+ (1,0) [0|32767] "" XXX + SG_ NEW_SIGNAL_3 : 32|4@1+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_4 : 40|8@1+ (1,0) [0|1] "" XXX + SG_ NEW_SIGNAL_2 : 48|8@1+ (1,0) [0|16777215] "" XXX BO_ 872 NEW_MSG_15: 8 XXX - SG_ NEW_SIGNAL_1 : 31|8@0+ (1,0) [0|65535] "" XXX + SG_ NEW_SIGNAL_1 : 24|8@1+ (1,0) [0|65535] "" XXX BO_ 977 NEW_MSG_12: 8 XXX SG_ NEW_SIGNAL_1 : 0|8@1+ (1,0) [0|255] "" XXX SG_ NEW_SIGNAL_2 : 16|12@1+ (1,0) [0|255] "" XXX BO_ 1632 Huge_Counter: 8 XXX - SG_ NEW_SIGNAL_1 : 31|8@0+ (1,0) [0|255] "" XXX SG_ Counter : 55|16@0+ (1,0) [0|255] "" XXX + SG_ NEW_SIGNAL_1 : 31|8@0+ (1,0) [0|255] "" XXX BO_ 1745 NEW_MSG_11: 8 XXX SG_ NEW_SIGNAL_1 : 24|6@1+ (1,0) [0|255] "" XXX @@ -332,8 +329,8 @@ BO_ 1745 NEW_MSG_11: 8 XXX SG_ NEW_SIGNAL_3 : 0|8@1+ (1,0) [0|255] "" XXX BO_ 1786 NEW_MSG_9: 8 XXX - SG_ Counter : 3|4@0+ (1,0) [0|255] "" XXX SG_ NEW_SIGNAL_2 : 8|16@1+ (1,0) [0|15] "" XXX + SG_ Counter : 0|4@1+ (1,0) [0|255] "" XXX @@ -346,26 +343,28 @@ CM_ SG_ 320 Off_Throttle_2 "Less sensitive"; CM_ SG_ 320 Throttle_Body_ "Throttle related"; CM_ SG_ 328 Gear "15 = P, 14 = R, 0 = N, 1-6=gear"; CM_ SG_ 328 Gear_2 "15 = P, 14 = R, 0 = N, 1-6=gear"; -CM_ SG_ 353 NEW_SIGNAL_3_Blank "always 2"; -CM_ SG_ 353 NEW_SIGNAL_2_Blank "0"; -CM_ SG_ 353 NEW_SIGNAL_9 "flipped around quick engagement"; -CM_ SG_ 353 NEW_SIGNAL_6_Blank "always 1"; +CM_ SG_ 353 Button "1 = main, 2 = set shallow, 3 = set deep, 4 = resume shallow, 5 resume deep"; CM_ SG_ 353 Brake_On "long activatedish"; +CM_ SG_ 353 SET_1 "always 1"; +CM_ SG_ 353 SET_2 ""; +CM_ SG_ 353 NEW_SIGNAL_9 "flipped around quick engagement"; CM_ SG_ 354 RPM "20hz version of Transmission_Engine under Transmission"; -CM_ SG_ 358 Car_Follow "front car detected"; -CM_ SG_ 358 ES_Error "No engagement until restart"; -CM_ SG_ 358 Cruise_Activated "is 1 when cruise is able to go"; -CM_ SG_ 358 Disengage_Alert "seatbelt and steep hill disengage"; CM_ SG_ 358 3SecondDisengage "seatbelt disengage"; -CM_ SG_ 359 All_depart_2015 "always 1 on 2017"; -CM_ SG_ 359 LKAS_Inactive_2017 "1 when not steering, 0 when lkas steering"; -CM_ SG_ 359 Sig2All_Depart "Left and right depart"; -CM_ SG_ 359 Sig1All_Depart "Left and right depart"; +CM_ SG_ 358 Disengage_Alert "seatbelt and steep hill disengage"; +CM_ SG_ 358 Cruise_Activated "is 1 when cruise is able to go"; +CM_ SG_ 358 ES_Error "No engagement until restart"; +CM_ SG_ 358 Lead_Car "front car detected"; CM_ SG_ 359 Sig1Right_Depart "right depart, hill steep and seatbelt disengage"; +CM_ SG_ 359 LKAS_Inactive_2017 "1 when not steering, 0 when lkas steering"; CM_ SG_ 359 Sig1Right_Depart_Front "object in front, right depart, hill steep and seatbelt disengage alert "; CM_ SG_ 359 Left_Depart_Front "warning after acceleration into car in front and left depart"; +CM_ SG_ 359 Alerts "2 = lead beep"; +CM_ SG_ 359 Sig1All_Depart "Left and right depart"; +CM_ SG_ 359 Sig2All_Depart "Left and right depart"; +CM_ SG_ 359 All_depart_2015 "always 1 on 2017"; CM_ SG_ 642 Counter "Affected by signals"; CM_ SG_ 642 RIGHT_BLINKER "0 off, 2 right, 1 left"; +CM_ SG_ 642 SEATBELT_FL ""; CM_ SG_ 880 Steering_Voltage_Flat "receives later than 371"; CM_ SG_ 880 NEW_SIGNAL_1 "0 in 2017"; CM_ SG_ 880 NEW_SIGNAL_4_2017 "1 in 2017";