diff --git a/.gitignore b/.gitignore index 623c45d79..cfd789ec1 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,6 @@ selfdrive/visiond/visiond /src/ one +openpilot +xx + diff --git a/README.md b/README.md index 90a182443..772e41a9b 100644 --- a/README.md +++ b/README.md @@ -92,8 +92,6 @@ Supported Cars | Kia | Sorento 2018 | All | Yes | Stock | 0mph | 0mph | Custom6| | Kia | Stinger 2018 | SCC + LKAS | Yes | Stock | 0mph | 0mph | Custom6| | Lexus | RX Hybrid 2016-19 | All | Yes | Yes2| 0mph | 0mph | Toyota | -| Subaru | Crosstrek 2018 | EyeSight | Yes | Stock | 0mph | 0mph | Subaru | -| Subaru | Impreza 2019 | EyeSight | Yes | Stock | 0mph | 0mph | Subaru | | Toyota | Avalon 2016 | TSS-P | Yes | Yes2| 20mph1| 0mph | Toyota | | Toyota | Camry 20184 | All | Yes | Stock | 0mph5 | 0mph | Toyota | | Toyota | C-HR 2017-184 | All | Yes | Stock | 0mph | 0mph | Toyota | @@ -109,13 +107,13 @@ Supported Cars | Toyota | Rav4 2019 | All | Yes | Yes | 0mph | 0mph | Toyota | | Toyota | Rav4 Hybrid 2017-18 | All | Yes | Yes2| 0mph | 0mph | Toyota | -1[Comma Pedal](https://community.comma.ai/wiki/index.php/Comma_Pedal) is used to provide stop-and-go capability to some of the openpilot-supported cars that don't currently support stop-and-go. Here is how to [build a Comma Pedal](https://medium.com/@jfrux/comma-pedal-building-with-macrofab-6328bea791e8). ***NOTE: The Comma Pedal is not officially supported by [comma.ai](https://comma.ai)*** -2When disconnecting the Driver Support Unit (DSU), otherwise longitudinal control is stock ACC. For DSU locations, see [Toyota Wiki page](https://community.comma.ai/wiki/index.php/Toyota) -3[GM installation guide](https://zoneos.com/volt/). -4It needs an extra 120Ohm resistor ([pic1](https://i.imgur.com/CmdKtTP.jpg), [pic2](https://i.imgur.com/s2etUo6.jpg)) on bus 3 and giraffe switches set to 01X1 (11X1 for stock LKAS), where X depends on if you have the [comma power](https://comma.ai/shop/products/power/). -528mph for Camry 4CYL L, 4CYL LE and 4CYL SE which don't have Full-Speed Range Dynamic Radar Cruise Control. -6Open sourced [Hyundai Giraffe](https://github.com/commaai/neo/tree/master/giraffe/hyundai) is designed for the 2019 Sante Fe; pinout may differ for other Hyundais. -7Community built Giraffe, find more information [here](https://zoneos.com/shop/). +1[Comma Pedal](https://community.comma.ai/wiki/index.php/Comma_Pedal) is used to provide stop-and-go capability to some of the openpilot-supported cars that don't currently support stop-and-go. Here is how to [build a Comma Pedal](https://medium.com/@jfrux/comma-pedal-building-with-macrofab-6328bea791e8). ***NOTE: The Comma Pedal is not officially supported by [comma.ai](https://comma.ai)*** +2When disconnecting the Driver Support Unit (DSU), otherwise longitudinal control is stock ACC. For DSU locations, see [Toyota Wiki page](https://community.comma.ai/wiki/index.php/Toyota) +3[GM installation guide](https://zoneos.com/volt/). +4It needs an extra 120Ohm resistor ([pic1](https://i.imgur.com/CmdKtTP.jpg), [pic2](https://i.imgur.com/s2etUo6.jpg)) on bus 3 and giraffe switches set to 01X1 (11X1 for stock LKAS), where X depends on if you have the [comma power](https://comma.ai/shop/products/power/). +528mph for Camry 4CYL L, 4CYL LE and 4CYL SE which don't have Full-Speed Range Dynamic Radar Cruise Control. +6Open sourced [Hyundai Giraffe](https://github.com/commaai/neo/tree/master/giraffe/hyundai) is designed for the 2019 Sante Fe; pinout may differ for other Hyundais. +7Community built Giraffe, find more information [here](https://zoneos.com/shop/). Community Maintained Cars ------ @@ -173,7 +171,6 @@ Directory structure ├── locationd # Soon to be home of precise location ├── logcatd # Android logcat as a service ├── loggerd # Logger and uploader of car data - ├── mapd # Fetches map data and computes next global path ├── proclogd # Logs information from proc ├── sensord # IMU / GPS interface code ├── test # Car simulator running code through virtual maneuvers diff --git a/RELEASES.md b/RELEASES.md index 0ae93ba2b..50e71874b 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,13 @@ +Version 0.5.13 (2019-05-31) +========================== + * Reduce panda power consumption by 70%, down to 80mW, when car is off (not for GM) + * Reduce EON power consumption by 40%, down to 1100mW, when car is off + * Reduce CPU utilization by 20% and improve stability + * Temporarily remove mapd functionalities to improve stability + * Add openpilot record-only mode for unsupported cars + * Synchronize controlsd to boardd to reduce latency + * Remove panda support for Subaru giraffe + Version 0.5.12 (2019-05-16) ========================== * Improve lateral control for the Prius and Prius Prime diff --git a/apk/ai.comma.plus.offroad.apk b/apk/ai.comma.plus.offroad.apk index b572a93fa..4ab1da4ce 100644 Binary files a/apk/ai.comma.plus.offroad.apk and b/apk/ai.comma.plus.offroad.apk differ diff --git a/cereal/car.capnp b/cereal/car.capnp index fe0d84e25..b33ab97c8 100644 --- a/cereal/car.capnp +++ b/cereal/car.capnp @@ -74,6 +74,7 @@ struct CarEvent @0x9b1657f34caf3ad3 { invalidGiraffeHonda @49; vehicleModelInvalid @50; controlsFailed @51; + sensorDataInvalid @52; } } @@ -175,7 +176,7 @@ struct CarState { # ******* radar state @ 20hz ******* -struct RadarState { +struct RadarData @0x888ad6581cf0aacb { errors @0 :List(Error); points @1 :List(RadarPoint); @@ -333,6 +334,7 @@ struct CarParams { steerActuatorDelay @36 :Float32; # Steering wheel actuator delay in seconds openpilotLongitudinalControl @37 :Bool; # is openpilot doing the longitudinal control? + carVin @38 :Text; # VIN number queried during fingerprinting struct LateralPIDTuning { kpBP @0 :List(Float32); diff --git a/cereal/log.capnp b/cereal/log.capnp index 84f0a3e80..7276e20b5 100644 --- a/cereal/log.capnp +++ b/cereal/log.capnp @@ -305,12 +305,12 @@ struct LiveUI { awarenessStatus @3 :Float32; } -struct Live20Data { +struct RadarState @0x9a185389d6fdd05f { canMonoTimes @10 :List(UInt64); mdMonoTime @6 :UInt64; ftMonoTimeDEPRECATED @7 :UInt64; - l100MonoTime @11 :UInt64; - radarErrors @12 :List(Car.RadarState.Error); + controlsStateMonoTime @11 :UInt64; + radarErrors @12 :List(Car.RadarData.Error); # all deprecated warpMatrixDEPRECATED @0 :List(Float32); @@ -368,15 +368,15 @@ struct LiveTracks { oncoming @9 :Bool; } -struct Live100Data { +struct ControlsState @0x97ff69c53601abf1 { canMonoTimeDEPRECATED @16 :UInt64; canMonoTimes @21 :List(UInt64); - l20MonoTimeDEPRECATED @17 :UInt64; + radarStateMonoTimeDEPRECATED @17 :UInt64; mdMonoTimeDEPRECATED @18 :UInt64; planMonoTime @28 :UInt64; pathPlanMonoTime @50 :UInt64; - state @31 :ControlState; + state @31 :OpenpilotState; vEgo @0 :Float32; vEgoRaw @32 :Float32; aEgoDEPRECATED @1 :Float32; @@ -433,7 +433,7 @@ struct Live100Data { pidState @53 :LateralPIDState; } - enum ControlState { + enum OpenpilotState @0xdbe58b96d2d1ac61 { disabled @0; preEnabled @1; enabled @2; @@ -507,6 +507,7 @@ struct ModelData { points @0 :List(Float32); prob @1 :Float32; std @2 :Float32; + stds @3 :List(Float32); } struct LeadData { @@ -574,7 +575,7 @@ struct LogRotate { struct Plan { mdMonoTime @9 :UInt64; - l20MonoTime @10 :UInt64; + radarStateMonoTime @10 :UInt64; eventsDEPRECATED @13 :List(Car.CarEvent); # lateral, 3rd order polynomial @@ -648,6 +649,7 @@ struct PathPlan { paramsValid @10 :Bool; modelValid @12 :Bool; angleOffset @11 :Float32; + sensorValid @14 :Bool; } struct LiveLocationData { @@ -1643,6 +1645,7 @@ struct LiveParametersData { angleOffsetAverage @3 :Float32; stiffnessFactor @4 :Float32; steerRatio @5 :Float32; + sensorValid @6 :Bool; } struct LiveMapData { @@ -1690,13 +1693,13 @@ struct Event { sensorEventDEPRECATED @4 :SensorEventData; can @5 :List(CanData); thermal @6 :ThermalData; - live100 @7 :Live100Data; + controlsState @7 :ControlsState; liveEventDEPRECATED @8 :List(LiveEventData); model @9 :ModelData; features @10 :CalibrationFeatures; sensorEvents @11 :List(SensorEventData); health @12 :HealthData; - live20 @13 :Live20Data; + radarState @13 :RadarState; liveUIDEPRECATED @14 :LiveUI; encodeIdx @15 :EncodeIndex; liveTracks @16 :List(LiveTracks); diff --git a/common/clock.pyx b/common/clock.pyx new file mode 100644 index 000000000..6205eca10 --- /dev/null +++ b/common/clock.pyx @@ -0,0 +1,16 @@ +from posix.time cimport clock_gettime, timespec, CLOCK_BOOTTIME, CLOCK_MONOTONIC_RAW + +cdef double readclock(int clock_id): + cdef timespec ts + cdef double current + + clock_gettime(clock_id, &ts) + current = ts.tv_sec + (ts.tv_nsec / 1000000000.) + return current + + +def monotonic_time(): + return readclock(CLOCK_MONOTONIC_RAW) + +def sec_since_boot(): + return readclock(CLOCK_BOOTTIME) diff --git a/common/file_helpers.py b/common/file_helpers.py new file mode 100644 index 000000000..bdfe9d0ec --- /dev/null +++ b/common/file_helpers.py @@ -0,0 +1,103 @@ +import os +import shutil +import tempfile +from atomicwrites import AtomicWriter + +def mkdirs_exists_ok(path): + try: + os.makedirs(path) + except OSError: + if not os.path.isdir(path): + raise + +def rm_not_exists_ok(path): + try: + os.remove(path) + except OSError: + if os.path.exists(path): + raise + +def rm_tree_or_link(path): + if os.path.islink(path): + os.unlink(path) + elif os.path.isdir(path): + shutil.rmtree(path) + +def get_tmpdir_on_same_filesystem(path): + # TODO(mgraczyk): HACK, we should actually check for which filesystem. + normpath = os.path.normpath(path) + parts = normpath.split("/") + if len(parts) > 1: + if parts[1].startswith("raid"): + if len(parts) > 2 and parts[2] == "runner": + return "/{}/runner/tmp".format(parts[1]) + elif len(parts) > 2 and parts[2] == "aws": + return "/{}/aws/tmp".format(parts[1]) + else: + return "/{}/tmp".format(parts[1]) + elif parts[1] == "aws": + return "/aws/tmp" + elif parts[1] == "scratch": + return "/scratch/tmp" + return "/tmp" + +class AutoMoveTempdir(object): + def __init__(self, target_path, temp_dir=None): + self._target_path = target_path + self._path = tempfile.mkdtemp(dir=temp_dir) + + @property + def name(self): + return self._path + + def close(self): + os.rename(self._path, self._target_path) + + def __enter__(self): return self + + def __exit__(self, type, value, traceback): + if type is None: + self.close() + else: + shutil.rmtree(self._path) + +class NamedTemporaryDir(object): + def __init__(self, temp_dir=None): + self._path = tempfile.mkdtemp(dir=temp_dir) + + @property + def name(self): + return self._path + + def close(self): + shutil.rmtree(self._path) + + def __enter__(self): return self + + def __exit__(self, type, value, traceback): + self.close() + +def _get_fileobject_func(writer, temp_dir): + def _get_fileobject(): + file_obj = writer.get_fileobject(dir=temp_dir) + os.chmod(file_obj.name, 0o644) + return file_obj + return _get_fileobject + +def atomic_write_on_fs_tmp(path, **kwargs): + """Creates an atomic writer using a temporary file in a temporary directory + on the same filesystem as path. + """ + # TODO(mgraczyk): This use of AtomicWriter relies on implementation details to set the temp + # directory. + writer = AtomicWriter(path, **kwargs) + return writer._open(_get_fileobject_func(writer, get_tmpdir_on_same_filesystem(path))) + + +def atomic_write_in_dir(path, **kwargs): + """Creates an atomic writer using a temporary file in the same directory + as the destination file. + """ + writer = AtomicWriter(path, **kwargs) + return writer._open(_get_fileobject_func(writer, os.path.dirname(path))) + diff --git a/common/params.py b/common/params.py index 30ebaa060..cde03156f 100755 --- a/common/params.py +++ b/common/params.py @@ -41,7 +41,7 @@ def mkdirs_exists_ok(path): class TxType(Enum): PERSISTENT = 1 CLEAR_ON_MANAGER_START = 2 - CLEAR_ON_CAR_START = 3 + CLEAR_ON_PANDA_DISCONNECT = 3 class UnknownKeyName(Exception): @@ -49,32 +49,33 @@ class UnknownKeyName(Exception): keys = { - "AccessToken": TxType.PERSISTENT, - "CalibrationParams": TxType.PERSISTENT, - "CarParams": TxType.CLEAR_ON_CAR_START, - "CompletedTrainingVersion": TxType.PERSISTENT, - "ControlsParams": TxType.PERSISTENT, - "DoUninstall": TxType.CLEAR_ON_MANAGER_START, - "DongleId": TxType.PERSISTENT, - "GitBranch": TxType.PERSISTENT, - "GitCommit": TxType.PERSISTENT, - "GitRemote": TxType.PERSISTENT, - "HasAcceptedTerms": TxType.PERSISTENT, - "IsDriverMonitoringEnabled": TxType.PERSISTENT, - "IsFcwEnabled": TxType.PERSISTENT, - "IsGeofenceEnabled": TxType.PERSISTENT, - "IsMetric": TxType.PERSISTENT, - "IsUpdateAvailable": TxType.PERSISTENT, - "IsUploadVideoOverCellularEnabled": TxType.PERSISTENT, - "LimitSetSpeed": TxType.PERSISTENT, - "LiveParameters": TxType.PERSISTENT, - "LongitudinalControl": TxType.PERSISTENT, - "Passive": TxType.PERSISTENT, - "RecordFront": TxType.PERSISTENT, - "ShouldDoUpdate": TxType.CLEAR_ON_MANAGER_START, - "SpeedLimitOffset": TxType.PERSISTENT, - "TrainingVersion": TxType.PERSISTENT, - "Version": TxType.PERSISTENT, + "AccessToken": [TxType.PERSISTENT], + "CalibrationParams": [TxType.PERSISTENT], + "CarParams": [TxType.CLEAR_ON_MANAGER_START, TxType.CLEAR_ON_PANDA_DISCONNECT], + "CompletedTrainingVersion": [TxType.PERSISTENT], + "ControlsParams": [TxType.PERSISTENT], + "DoUninstall": [TxType.CLEAR_ON_MANAGER_START], + "DongleId": [TxType.PERSISTENT], + "GitBranch": [TxType.PERSISTENT], + "GitCommit": [TxType.PERSISTENT], + "GitRemote": [TxType.PERSISTENT], + "HasAcceptedTerms": [TxType.PERSISTENT], + "IsDriverMonitoringEnabled": [TxType.PERSISTENT], + "IsFcwEnabled": [TxType.PERSISTENT], + "IsGeofenceEnabled": [TxType.PERSISTENT], + "IsMetric": [TxType.PERSISTENT], + "IsUpdateAvailable": [TxType.PERSISTENT], + "IsUploadVideoOverCellularEnabled": [TxType.PERSISTENT], + "LimitSetSpeed": [TxType.PERSISTENT], + "LiveParameters": [TxType.PERSISTENT], + "LongitudinalControl": [TxType.PERSISTENT], + "Passive": [TxType.PERSISTENT], + "RecordFront": [TxType.PERSISTENT], + "ShouldDoUpdate": [TxType.CLEAR_ON_MANAGER_START], + "SpeedLimitOffset": [TxType.PERSISTENT], + "SubscriberInfo": [TxType.PERSISTENT], + "TrainingVersion": [TxType.PERSISTENT], + "Version": [TxType.PERSISTENT], } @@ -308,14 +309,14 @@ class Params(object): def _clear_keys_with_type(self, tx_type): with self.transaction(write=True) as txn: for key in keys: - if keys[key] == tx_type: + if tx_type in keys[key]: txn.delete(key) def manager_start(self): self._clear_keys_with_type(TxType.CLEAR_ON_MANAGER_START) - def car_start(self): - self._clear_keys_with_type(TxType.CLEAR_ON_CAR_START) + def panda_disconnect(self): + self._clear_keys_with_type(TxType.CLEAR_ON_PANDA_DISCONNECT) def delete(self, key): with self.transaction(write=True) as txn: diff --git a/common/realtime.py b/common/realtime.py index 7fe183fb2..21204db0d 100644 --- a/common/realtime.py +++ b/common/realtime.py @@ -2,58 +2,24 @@ import os import time import platform -import threading import subprocess import multiprocessing - from cffi import FFI + +# Build and load cython module +import pyximport +installer = pyximport.install(inplace=True, build_dir='/tmp') +from common.clock import monotonic_time, sec_since_boot # pylint: disable=no-name-in-module, import-error +pyximport.uninstall(*installer) +assert monotonic_time +assert sec_since_boot + + ffi = FFI() -ffi.cdef(""" - -typedef int clockid_t; -struct timespec { - long tv_sec; /* Seconds. */ - long tv_nsec; /* Nanoseconds. */ -}; -int clock_gettime (clockid_t clk_id, struct timespec *tp); - -long syscall(long number, ...); - -""" -) +ffi.cdef("long syscall(long number, ...);") libc = ffi.dlopen(None) -# see -CLOCK_MONOTONIC_RAW = 4 -CLOCK_BOOTTIME = 7 - -if platform.system() != 'Darwin' and hasattr(libc, 'clock_gettime'): - c_clock_gettime = libc.clock_gettime - - tlocal = threading.local() - def clock_gettime(clk_id): - if not hasattr(tlocal, 'ts'): - tlocal.ts = ffi.new('struct timespec *') - - ts = tlocal.ts - - r = c_clock_gettime(clk_id, ts) - if r != 0: - raise OSError("clock_gettime") - return ts.tv_sec + ts.tv_nsec * 1e-9 -else: - # hack. only for OS X < 10.12 - def clock_gettime(clk_id): - return time.time() - -def monotonic_time(): - return clock_gettime(CLOCK_MONOTONIC_RAW) - -def sec_since_boot(): - return clock_gettime(CLOCK_BOOTTIME) - - def set_realtime_priority(level): if os.getuid() != 0: print("not setting priority, not root") @@ -99,10 +65,9 @@ class Ratekeeper(object): lagged = False remaining = self._next_frame_time - sec_since_boot() self._next_frame_time += self._interval - if remaining < -self._print_delay_threshold: + if self._print_delay_threshold is not None and remaining < -self._print_delay_threshold: print("%s lagging by %.2f ms" % (self._process_name, -remaining * 1000)) lagged = True self._frame += 1 self._remaining = remaining return lagged - diff --git a/common/vin.py b/common/vin.py new file mode 100755 index 000000000..29357e34b --- /dev/null +++ b/common/vin.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python +import time +from common.realtime import sec_since_boot +import selfdrive.messaging as messaging +from selfdrive.boardd.boardd import can_list_to_can_capnp + +def get_vin(logcan, sendcan): + + # works on standard 11-bit addresses for diagnostic. Tested on Toyota and Subaru; + # Honda uses the extended 29-bit addresses, and unfortunately only works from OBDII + query_msg = [[0x7df, 0, '\x02\x09\x02'.ljust(8, "\x00"), 0], + [0x7e0, 0, '\x30'.ljust(8, "\x00"), 0]] + + cnts = [1, 2] # Number of messages to wait for at each iteration + vin_valid = True + + dat = [] + for i in range(len(query_msg)): + cnt = 0 + sendcan.send(can_list_to_can_capnp([query_msg[i]], msgtype='sendcan')) + got_response = False + t_start = sec_since_boot() + while sec_since_boot() - t_start < 0.05 and not got_response: + for a in messaging.drain_sock(logcan): + for can in a.can: + if can.src == 0 and can.address == 0x7e8: + vin_valid = vin_valid and is_vin_response_valid(can.dat, i, cnt) + dat += can.dat[2:] if i == 0 else can.dat[1:] + cnt += 1 + if cnt == cnts[i]: + got_response = True + time.sleep(0.01) + + return "".join(dat[3:]) if vin_valid else "" + +""" +if 'vin' not in gctx: + print "getting vin" + gctx['vin'] = query_vin()[3:] + print "got VIN %s" % (gctx['vin'],) + cloudlog.info("got VIN %s" % (gctx['vin'],)) + +# *** determine platform based on VIN **** +if vin.startswith("19UDE2F36G"): + print "ACURA ILX 2016" + self.civic = False +else: + # TODO: add Honda check explicitly + print "HONDA CIVIC 2016" + self.civic = True + +# *** special case VIN of Acura test platform +if vin == "19UDE2F36GA001322": + print "comma.ai test platform detected" + # it has a gas interceptor and a torque mod + self.torque_mod = True +""" + + +# sanity checks on response messages from vin query +def is_vin_response_valid(can_dat, step, cnt): + + can_dat = [ord(i) for i in can_dat] + + if len(can_dat) != 8: + # ISO-TP meesages are all 8 bytes + return False + + if step == 0: + # VIN does not fit in a single message and it's 20 bytes of data + if can_dat[0] != 0x10 or can_dat[1] != 0x14: + return False + + if step == 1 and cnt == 0: + # first response after a CONTINUE query is sent + if can_dat[0] != 0x21: + return False + + if step == 1 and cnt == 1: + # second response after a CONTINUE query is sent + if can_dat[0] != 0x22: + return False + + return True + + +if __name__ == "__main__": + import zmq + from selfdrive.services import service_list + context = zmq.Context() + logcan = messaging.sub_sock(context, service_list['can'].port) + sendcan = messaging.pub_sock(context, service_list['sendcan'].port) + time.sleep(1.) # give time to sendcan socket to start + + print get_vin(logcan, sendcan) diff --git a/installer/updater/updater b/installer/updater/updater index 0b8602b35..84a8614d5 100755 Binary files a/installer/updater/updater and b/installer/updater/updater differ diff --git a/opendbc/acura_ilx_2016_can_generated.dbc b/opendbc/acura_ilx_2016_can_generated.dbc index dd112ca32..e2e853ea1 100644 --- a/opendbc/acura_ilx_2016_can_generated.dbc +++ b/opendbc/acura_ilx_2016_can_generated.dbc @@ -164,14 +164,15 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03 : 47|2@0+ (1,0) [0|3] "" BDY + SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03_2 : 55|2@0+ (1,0) [0|3] "" 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_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY diff --git a/opendbc/acura_rdx_2018_can_generated.dbc b/opendbc/acura_rdx_2018_can_generated.dbc index a8e69b14e..e40672eac 100644 --- a/opendbc/acura_rdx_2018_can_generated.dbc +++ b/opendbc/acura_rdx_2018_can_generated.dbc @@ -164,14 +164,15 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03 : 47|2@0+ (1,0) [0|3] "" BDY + SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03_2 : 55|2@0+ (1,0) [0|3] "" 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_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY diff --git a/opendbc/generator/honda/_bosch_2018.dbc b/opendbc/generator/honda/_bosch_2018.dbc index 0b8d8a17f..302c254c2 100644 --- a/opendbc/generator/honda/_bosch_2018.dbc +++ b/opendbc/generator/honda/_bosch_2018.dbc @@ -196,7 +196,8 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ ACC_PROBLEM : 37|1@0+ (1,0) [0|1] "" BDY SG_ ACC_ON : 52|1@0+ (1,0) [0|1] "" XXX SG_ BOH_6 : 51|4@0+ (1,0) [0|15] "" XXX - SG_ SET_TO_X3 : 55|2@0+ (1,0) [0|3] "" XXX + SG_ IMPERIAL_UNIT : 55|1@0+ (1,0) [0|1] "" XXX + SG_ SET_TO_X1 : 56|1@0+ (1,0) [0|1] "" XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX @@ -260,4 +261,4 @@ BO_ 891 STALK_STATUS_2: 8 XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON -VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; \ No newline at end of file +VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; diff --git a/opendbc/generator/honda/_honda_2017.dbc b/opendbc/generator/honda/_honda_2017.dbc index c79f2587b..77d29d429 100644 --- a/opendbc/generator/honda/_honda_2017.dbc +++ b/opendbc/generator/honda/_honda_2017.dbc @@ -142,14 +142,15 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03 : 47|2@0+ (1,0) [0|3] "" BDY + SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03_2 : 55|2@0+ (1,0) [0|3] "" 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_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY diff --git a/opendbc/generator/honda/honda_civic_touring_2016_can.dbc b/opendbc/generator/honda/honda_civic_touring_2016_can.dbc index 3207c7b97..1a7579d2a 100644 --- a/opendbc/generator/honda/honda_civic_touring_2016_can.dbc +++ b/opendbc/generator/honda/honda_civic_touring_2016_can.dbc @@ -50,8 +50,8 @@ BO_ 450 EPB_STATUS: 8 EPB SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON -BO_ 493 HUD_SETTING: 8 XXX - SG_ SPEED_UNIT : 5|1@0+ (1,0) [0|1] "" EON +BO_ 493 HUD_SETTING: 5 XXX + SG_ IMPERIAL_UNIT : 5|1@0+ (1,0) [0|1] "" EON BO_ 487 BRAKE_PRESSURE: 4 VSA SG_ BRAKE_PRESSURE1 : 7|10@0+ (0.015625,-103) [0|1000] "" EON @@ -128,7 +128,6 @@ VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_spe VAL_ 401 GEAR_SHIFTER 32 "L" 16 "S" 8 "D" 4 "N" 2 "R" 1 "P" ; VAL_ 401 GEAR 7 "L" 10 "S" 4 "D" 3 "N" 2 "R" 1 "P" ; VAL_ 450 EPB_STATE 3 "engaged" 2 "disengaging" 1 "engaging" 0 "disengaged" ; -VAL_ 493 SPEED_UNIT 1 "mph" 0 "kph" ; VAL_ 545 ECON_ON_2 0 "off" 3 "on" ; VAL_ 662 CRUISE_BUTTONS 7 "tbd" 6 "tbd" 5 "tbd" 4 "accel_res" 3 "decel_set" 2 "cancel" 1 "main" 0 "none" ; VAL_ 662 CRUISE_SETTING 3 "distance_adj" 2 "tbd" 1 "lkas_button" 0 "none" ; diff --git a/opendbc/generator/toyota/_toyota_2017.dbc b/opendbc/generator/toyota/_toyota_2017.dbc index 0e2a242b1..58cc33001 100644 --- a/opendbc/generator/toyota/_toyota_2017.dbc +++ b/opendbc/generator/toyota/_toyota_2017.dbc @@ -91,7 +91,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 643 PRE_COLLISION: 8 XXX diff --git a/opendbc/honda_accord_lx15t_2018_can_generated.dbc b/opendbc/honda_accord_lx15t_2018_can_generated.dbc index 788963849..6159efb0e 100644 --- a/opendbc/honda_accord_lx15t_2018_can_generated.dbc +++ b/opendbc/honda_accord_lx15t_2018_can_generated.dbc @@ -200,7 +200,8 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ ACC_PROBLEM : 37|1@0+ (1,0) [0|1] "" BDY SG_ ACC_ON : 52|1@0+ (1,0) [0|1] "" XXX SG_ BOH_6 : 51|4@0+ (1,0) [0|15] "" XXX - SG_ SET_TO_X3 : 55|2@0+ (1,0) [0|3] "" XXX + SG_ IMPERIAL_UNIT : 55|1@0+ (1,0) [0|1] "" XXX + SG_ SET_TO_X1 : 56|1@0+ (1,0) [0|1] "" XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX @@ -265,6 +266,7 @@ BO_ 891 STALK_STATUS_2: 8 XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; + CM_ "honda_accord_lx15t_2018_can.dbc starts here" diff --git a/opendbc/honda_accord_s2t_2018_can_generated.dbc b/opendbc/honda_accord_s2t_2018_can_generated.dbc index 43a46aff8..7b3e99bc8 100644 --- a/opendbc/honda_accord_s2t_2018_can_generated.dbc +++ b/opendbc/honda_accord_s2t_2018_can_generated.dbc @@ -200,7 +200,8 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ ACC_PROBLEM : 37|1@0+ (1,0) [0|1] "" BDY SG_ ACC_ON : 52|1@0+ (1,0) [0|1] "" XXX SG_ BOH_6 : 51|4@0+ (1,0) [0|15] "" XXX - SG_ SET_TO_X3 : 55|2@0+ (1,0) [0|3] "" XXX + SG_ IMPERIAL_UNIT : 55|1@0+ (1,0) [0|1] "" XXX + SG_ SET_TO_X1 : 56|1@0+ (1,0) [0|1] "" XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX @@ -265,6 +266,7 @@ BO_ 891 STALK_STATUS_2: 8 XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; + CM_ "honda_accord_s2t_2018_can.dbc starts here" diff --git a/opendbc/honda_civic_hatchback_ex_2017_can_generated.dbc b/opendbc/honda_civic_hatchback_ex_2017_can_generated.dbc index bbf810dd7..55f74cf99 100644 --- a/opendbc/honda_civic_hatchback_ex_2017_can_generated.dbc +++ b/opendbc/honda_civic_hatchback_ex_2017_can_generated.dbc @@ -200,7 +200,8 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ ACC_PROBLEM : 37|1@0+ (1,0) [0|1] "" BDY SG_ ACC_ON : 52|1@0+ (1,0) [0|1] "" XXX SG_ BOH_6 : 51|4@0+ (1,0) [0|15] "" XXX - SG_ SET_TO_X3 : 55|2@0+ (1,0) [0|3] "" XXX + SG_ IMPERIAL_UNIT : 55|1@0+ (1,0) [0|1] "" XXX + SG_ SET_TO_X1 : 56|1@0+ (1,0) [0|1] "" XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX @@ -265,6 +266,7 @@ BO_ 891 STALK_STATUS_2: 8 XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; + CM_ "honda_civic_hatchback_ex_2017_can.dbc starts here" diff --git a/opendbc/honda_civic_touring_2016_can_generated.dbc b/opendbc/honda_civic_touring_2016_can_generated.dbc index 675e56f23..7e95e638b 100644 --- a/opendbc/honda_civic_touring_2016_can_generated.dbc +++ b/opendbc/honda_civic_touring_2016_can_generated.dbc @@ -164,14 +164,15 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03 : 47|2@0+ (1,0) [0|3] "" BDY + SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03_2 : 55|2@0+ (1,0) [0|3] "" 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_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY @@ -288,8 +289,8 @@ BO_ 450 EPB_STATUS: 8 EPB SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" EON -BO_ 493 HUD_SETTING: 8 XXX - SG_ SPEED_UNIT : 5|1@0+ (1,0) [0|1] "" EON +BO_ 493 HUD_SETTING: 5 XXX + SG_ IMPERIAL_UNIT : 5|1@0+ (1,0) [0|1] "" EON BO_ 487 BRAKE_PRESSURE: 4 VSA SG_ BRAKE_PRESSURE1 : 7|10@0+ (0.015625,-103) [0|1000] "" EON @@ -366,7 +367,6 @@ VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_spe VAL_ 401 GEAR_SHIFTER 32 "L" 16 "S" 8 "D" 4 "N" 2 "R" 1 "P" ; VAL_ 401 GEAR 7 "L" 10 "S" 4 "D" 3 "N" 2 "R" 1 "P" ; VAL_ 450 EPB_STATE 3 "engaged" 2 "disengaging" 1 "engaging" 0 "disengaged" ; -VAL_ 493 SPEED_UNIT 1 "mph" 0 "kph" ; VAL_ 545 ECON_ON_2 0 "off" 3 "on" ; VAL_ 662 CRUISE_BUTTONS 7 "tbd" 6 "tbd" 5 "tbd" 4 "accel_res" 3 "decel_set" 2 "cancel" 1 "main" 0 "none" ; VAL_ 662 CRUISE_SETTING 3 "distance_adj" 2 "tbd" 1 "lkas_button" 0 "none" ; diff --git a/opendbc/honda_crv_ex_2017_can_generated.dbc b/opendbc/honda_crv_ex_2017_can_generated.dbc index 56a6b4e1b..2a6449f52 100644 --- a/opendbc/honda_crv_ex_2017_can_generated.dbc +++ b/opendbc/honda_crv_ex_2017_can_generated.dbc @@ -200,7 +200,8 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ ACC_PROBLEM : 37|1@0+ (1,0) [0|1] "" BDY SG_ ACC_ON : 52|1@0+ (1,0) [0|1] "" XXX SG_ BOH_6 : 51|4@0+ (1,0) [0|15] "" XXX - SG_ SET_TO_X3 : 55|2@0+ (1,0) [0|3] "" XXX + SG_ IMPERIAL_UNIT : 55|1@0+ (1,0) [0|1] "" XXX + SG_ SET_TO_X1 : 56|1@0+ (1,0) [0|1] "" XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX @@ -265,6 +266,7 @@ BO_ 891 STALK_STATUS_2: 8 XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; + CM_ "honda_crv_ex_2017_can.dbc starts here" diff --git a/opendbc/honda_crv_hybrid_2019_can_generated.dbc b/opendbc/honda_crv_hybrid_2019_can_generated.dbc index 73e5a431c..4fd8ae924 100644 --- a/opendbc/honda_crv_hybrid_2019_can_generated.dbc +++ b/opendbc/honda_crv_hybrid_2019_can_generated.dbc @@ -200,7 +200,8 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ ACC_PROBLEM : 37|1@0+ (1,0) [0|1] "" BDY SG_ ACC_ON : 52|1@0+ (1,0) [0|1] "" XXX SG_ BOH_6 : 51|4@0+ (1,0) [0|15] "" XXX - SG_ SET_TO_X3 : 55|2@0+ (1,0) [0|3] "" XXX + SG_ IMPERIAL_UNIT : 55|1@0+ (1,0) [0|1] "" XXX + SG_ SET_TO_X1 : 56|1@0+ (1,0) [0|1] "" XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX @@ -265,6 +266,7 @@ BO_ 891 STALK_STATUS_2: 8 XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; + CM_ "honda_crv_hybrid_2019_can.dbc starts here" diff --git a/opendbc/honda_crv_touring_2016_can_generated.dbc b/opendbc/honda_crv_touring_2016_can_generated.dbc index aaee239b9..1e25cbf79 100644 --- a/opendbc/honda_crv_touring_2016_can_generated.dbc +++ b/opendbc/honda_crv_touring_2016_can_generated.dbc @@ -164,14 +164,15 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03 : 47|2@0+ (1,0) [0|3] "" BDY + SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03_2 : 55|2@0+ (1,0) [0|3] "" 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_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY diff --git a/opendbc/honda_fit_ex_2018_can_generated.dbc b/opendbc/honda_fit_ex_2018_can_generated.dbc index 62be687b1..fe3a4735c 100644 --- a/opendbc/honda_fit_ex_2018_can_generated.dbc +++ b/opendbc/honda_fit_ex_2018_can_generated.dbc @@ -164,14 +164,15 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03 : 47|2@0+ (1,0) [0|3] "" BDY + SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03_2 : 55|2@0+ (1,0) [0|3] "" 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_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY diff --git a/opendbc/honda_insight_ex_2019_can_generated.dbc b/opendbc/honda_insight_ex_2019_can_generated.dbc index f2874fa45..cbeff828b 100644 --- a/opendbc/honda_insight_ex_2019_can_generated.dbc +++ b/opendbc/honda_insight_ex_2019_can_generated.dbc @@ -200,7 +200,8 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ ACC_PROBLEM : 37|1@0+ (1,0) [0|1] "" BDY SG_ ACC_ON : 52|1@0+ (1,0) [0|1] "" XXX SG_ BOH_6 : 51|4@0+ (1,0) [0|15] "" XXX - SG_ SET_TO_X3 : 55|2@0+ (1,0) [0|3] "" XXX + SG_ IMPERIAL_UNIT : 55|1@0+ (1,0) [0|1] "" XXX + SG_ SET_TO_X1 : 56|1@0+ (1,0) [0|1] "" XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" XXX SG_ CHECKSUM : 59|4@0+ (1,0) [0|15] "" XXX @@ -265,6 +266,7 @@ BO_ 891 STALK_STATUS_2: 8 XXX SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" EON VAL_ 399 STEER_STATUS 6 "tmp_fault" 5 "fault_1" 4 "no_torque_alert_2" 3 "low_speed_lockout" 2 "no_torque_alert_1" 0 "normal" ; + CM_ "honda_insight_ex_2019_can.dbc starts here" diff --git a/opendbc/honda_odyssey_exl_2018_generated.dbc b/opendbc/honda_odyssey_exl_2018_generated.dbc index 6f00df2d4..3a95af4b2 100644 --- a/opendbc/honda_odyssey_exl_2018_generated.dbc +++ b/opendbc/honda_odyssey_exl_2018_generated.dbc @@ -164,14 +164,15 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03 : 47|2@0+ (1,0) [0|3] "" BDY + SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03_2 : 55|2@0+ (1,0) [0|3] "" 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_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY diff --git a/opendbc/honda_pilot_touring_2017_can_generated.dbc b/opendbc/honda_pilot_touring_2017_can_generated.dbc index 310de029b..50f2911a8 100644 --- a/opendbc/honda_pilot_touring_2017_can_generated.dbc +++ b/opendbc/honda_pilot_touring_2017_can_generated.dbc @@ -164,14 +164,15 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03 : 47|2@0+ (1,0) [0|3] "" BDY + SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03_2 : 55|2@0+ (1,0) [0|3] "" 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_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY diff --git a/opendbc/honda_ridgeline_black_edition_2017_can_generated.dbc b/opendbc/honda_ridgeline_black_edition_2017_can_generated.dbc index 04e1c78a2..725acb553 100644 --- a/opendbc/honda_ridgeline_black_edition_2017_can_generated.dbc +++ b/opendbc/honda_ridgeline_black_edition_2017_can_generated.dbc @@ -164,14 +164,15 @@ BO_ 780 ACC_HUD: 8 ADAS SG_ FCM_PROBLEM : 34|1@0+ (1,0) [0|1] "" BDY SG_ RADAR_OBSTRUCTED : 33|1@0+ (1,0) [0|1] "" BDY SG_ ENABLE_MINI_CAR : 32|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03 : 47|2@0+ (1,0) [0|3] "" BDY + SG_ HUD_DISTANCE : 47|2@0+ (1,0) [0|3] "" BDY SG_ HUD_LEAD : 45|2@0+ (1,0) [0|3] "" BDY SG_ BOH_3 : 43|1@0+ (1,0) [0|3] "" BDY SG_ BOH_4 : 42|1@0+ (1,0) [0|3] "" BDY SG_ BOH_5 : 41|1@0+ (1,0) [0|3] "" BDY SG_ CRUISE_CONTROL_LABEL : 40|1@0+ (1,0) [0|3] "" BDY SG_ HUD_DISTANCE_3 : 52|1@0+ (1,0) [0|1] "" BDY - SG_ SET_ME_X03_2 : 55|2@0+ (1,0) [0|3] "" 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_ SET_ME_X01 : 48|1@0+ (1,0) [0|1] "" BDY SG_ COUNTER : 61|2@0+ (1,0) [0|3] "" BDY SG_ CHECKSUM : 59|4@0+ (1,0) [0|3] "" BDY diff --git a/opendbc/lexus_gs300h_2017_pt_generated.dbc b/opendbc/lexus_gs300h_2017_pt_generated.dbc index 113f1101c..201098af8 100644 --- a/opendbc/lexus_gs300h_2017_pt_generated.dbc +++ b/opendbc/lexus_gs300h_2017_pt_generated.dbc @@ -125,7 +125,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 643 PRE_COLLISION: 8 XXX diff --git a/opendbc/lexus_is_2018_pt_generated.dbc b/opendbc/lexus_is_2018_pt_generated.dbc index 69e20ac67..a7acb08db 100644 --- a/opendbc/lexus_is_2018_pt_generated.dbc +++ b/opendbc/lexus_is_2018_pt_generated.dbc @@ -125,7 +125,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 643 PRE_COLLISION: 8 XXX diff --git a/opendbc/lexus_is_hybrid_2017_pt_generated.dbc b/opendbc/lexus_is_hybrid_2017_pt_generated.dbc index 75639c994..cbc770aa1 100644 --- a/opendbc/lexus_is_hybrid_2017_pt_generated.dbc +++ b/opendbc/lexus_is_hybrid_2017_pt_generated.dbc @@ -125,7 +125,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 643 PRE_COLLISION: 8 XXX diff --git a/opendbc/lexus_rx_hybrid_2017_pt_generated.dbc b/opendbc/lexus_rx_hybrid_2017_pt_generated.dbc index 26e0dd6a4..6f01126fa 100644 --- a/opendbc/lexus_rx_hybrid_2017_pt_generated.dbc +++ b/opendbc/lexus_rx_hybrid_2017_pt_generated.dbc @@ -125,7 +125,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 643 PRE_COLLISION: 8 XXX diff --git a/opendbc/toyota_avalon_2017_pt_generated.dbc b/opendbc/toyota_avalon_2017_pt_generated.dbc index 7e4742ea9..c93250fab 100644 --- a/opendbc/toyota_avalon_2017_pt_generated.dbc +++ b/opendbc/toyota_avalon_2017_pt_generated.dbc @@ -125,7 +125,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 643 PRE_COLLISION: 8 XXX diff --git a/opendbc/toyota_camry_hybrid_2018_pt_generated.dbc b/opendbc/toyota_camry_hybrid_2018_pt_generated.dbc index 066b41767..35b4d97e2 100644 --- a/opendbc/toyota_camry_hybrid_2018_pt_generated.dbc +++ b/opendbc/toyota_camry_hybrid_2018_pt_generated.dbc @@ -125,7 +125,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 643 PRE_COLLISION: 8 XXX diff --git a/opendbc/toyota_chr_2018_pt_generated.dbc b/opendbc/toyota_chr_2018_pt_generated.dbc index 16412c7bc..69ba26969 100644 --- a/opendbc/toyota_chr_2018_pt_generated.dbc +++ b/opendbc/toyota_chr_2018_pt_generated.dbc @@ -125,7 +125,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 643 PRE_COLLISION: 8 XXX diff --git a/opendbc/toyota_chr_hybrid_2018_pt_generated.dbc b/opendbc/toyota_chr_hybrid_2018_pt_generated.dbc index 961843924..5e53e1297 100644 --- a/opendbc/toyota_chr_hybrid_2018_pt_generated.dbc +++ b/opendbc/toyota_chr_hybrid_2018_pt_generated.dbc @@ -125,7 +125,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 643 PRE_COLLISION: 8 XXX diff --git a/opendbc/toyota_corolla_2017_pt_generated.dbc b/opendbc/toyota_corolla_2017_pt_generated.dbc index 866711e37..c24428f34 100644 --- a/opendbc/toyota_corolla_2017_pt_generated.dbc +++ b/opendbc/toyota_corolla_2017_pt_generated.dbc @@ -125,7 +125,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 643 PRE_COLLISION: 8 XXX diff --git a/opendbc/toyota_highlander_2017_pt_generated.dbc b/opendbc/toyota_highlander_2017_pt_generated.dbc index 64f920b4b..d9962c09b 100644 --- a/opendbc/toyota_highlander_2017_pt_generated.dbc +++ b/opendbc/toyota_highlander_2017_pt_generated.dbc @@ -125,7 +125,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 643 PRE_COLLISION: 8 XXX diff --git a/opendbc/toyota_highlander_hybrid_2018_pt_generated.dbc b/opendbc/toyota_highlander_hybrid_2018_pt_generated.dbc index b9a1febab..d7c53cde7 100644 --- a/opendbc/toyota_highlander_hybrid_2018_pt_generated.dbc +++ b/opendbc/toyota_highlander_hybrid_2018_pt_generated.dbc @@ -125,7 +125,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 643 PRE_COLLISION: 8 XXX diff --git a/opendbc/toyota_prius_2017_pt_generated.dbc b/opendbc/toyota_prius_2017_pt_generated.dbc index 23410f8e2..56c1e5f85 100644 --- a/opendbc/toyota_prius_2017_pt_generated.dbc +++ b/opendbc/toyota_prius_2017_pt_generated.dbc @@ -125,7 +125,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 643 PRE_COLLISION: 8 XXX diff --git a/opendbc/toyota_rav4_2017_pt_generated.dbc b/opendbc/toyota_rav4_2017_pt_generated.dbc index 89ad1378e..e507f13cd 100644 --- a/opendbc/toyota_rav4_2017_pt_generated.dbc +++ b/opendbc/toyota_rav4_2017_pt_generated.dbc @@ -125,7 +125,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 643 PRE_COLLISION: 8 XXX diff --git a/opendbc/toyota_rav4_hybrid_2017_pt_generated.dbc b/opendbc/toyota_rav4_hybrid_2017_pt_generated.dbc index 2d3e3bcc7..228d8f1b2 100644 --- a/opendbc/toyota_rav4_hybrid_2017_pt_generated.dbc +++ b/opendbc/toyota_rav4_hybrid_2017_pt_generated.dbc @@ -125,7 +125,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 643 PRE_COLLISION: 8 XXX diff --git a/opendbc/toyota_sienna_xle_2018_pt_generated.dbc b/opendbc/toyota_sienna_xle_2018_pt_generated.dbc index 256a702ab..1d4786f86 100644 --- a/opendbc/toyota_sienna_xle_2018_pt_generated.dbc +++ b/opendbc/toyota_sienna_xle_2018_pt_generated.dbc @@ -125,7 +125,7 @@ BO_ 614 STEERING_IPAS: 8 IPAS SG_ SET_ME_X00 : 31|8@0+ (1,0) [0|255] "" XXX SG_ DIRECTION_CMD : 38|2@0+ (1,0) [0|3] "" XXX SG_ SET_ME_X40 : 47|8@0+ (1,0) [0|255] "" XXX - SG_ SET_ME_X00 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ SET_ME_X00_1 : 55|8@0+ (1,0) [0|255] "" XXX SG_ CHECKSUM : 63|8@0+ (1,0) [0|255] "" XXX BO_ 643 PRE_COLLISION: 8 XXX diff --git a/opendbc/vw_mqb_2010.dbc b/opendbc/vw_mqb_2010.dbc index 9e7c7772a..4529f8847 100644 --- a/opendbc/vw_mqb_2010.dbc +++ b/opendbc/vw_mqb_2010.dbc @@ -1,7 +1,7 @@ VERSION "" -NS_ : +NS_ : NS_DESC_ CM_ BA_DEF_ @@ -33,97 +33,97 @@ NS_ : BS_: -BU_: Airbag_MQB BAP_Tester_MQB BMS_MQB Datenlogger_MQB Gateway_MQB Getriebe_DQ_Hybrid_MQB Getriebe_DQ_MQB LEH_MQB Motor_Diesel_MQB Motor_Hybrid_MQB Motor_Otto_MQB SAK_MQB Waehlhebel_MQB +BU_: Airbag_MQB BAP_Tester_MQB BMS_MQB Datenlogger_MQB Gateway_MQB Getriebe_DQ_Hybrid_MQB Getriebe_DQ_MQB LEH_MQB Motor_Diesel_MQB Motor_Hybrid_MQB Motor_Otto_MQB SAK_MQB Waehlhebel_MQB Vector__XXX 9 l c i XXX BO_ 290 ACC_06: 8 Gateway_MQB - SG_ ACC_06_CRC : 0|8@1+ (1,0) [0|255] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ACC_06_BZ : 8|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ACC_limitierte_Anfahrdyn : 12|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ACC_zul_Regelabw_unten : 16|6@1+ (0.024,0) [0|1.512] "Unit_MeterPerSeconSquar" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ACC_StartStopp_Info : 22|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB - SG_ ACC_Sollbeschleunigung_02 : 24|11@1+ (0.005,-7.22) [-7.22|3.005] "Unit_MeterPerSeconSquar" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ACC_zul_Regelabw_oben : 35|5@1+ (0.0625,0) [0|1.9375] "Unit_MeterPerSeconSquar" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ACC_neg_Sollbeschl_Grad_02 : 40|8@1+ (0.05,0) [0|12.75] "Unit_MeterPerCubicSecon" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ACC_pos_Sollbeschl_Grad_02 : 48|8@1+ (0.05,0) [0|12.75] "Unit_MeterPerCubicSecon" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ACC_Anfahren : 56|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ACC_Anhalten : 57|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ACC_Typ : 58|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ACC_Status_ACC : 60|3@1+ (1,0) [0|7] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ACC_Minimale_Bremsung : 63|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ACC_06_CRC : 0|8@1+ (1,0) [0|255] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ACC_06_BZ : 8|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ACC_limitierte_Anfahrdyn : 12|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ACC_zul_Regelabw_unten : 16|6@1+ (0.024,0) [0|1.512] "Unit_MeterPerSeconSquar" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ACC_StartStopp_Info : 22|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ ACC_Sollbeschleunigung_02 : 24|11@1+ (0.005,-7.22) [-7.22|3.005] "Unit_MeterPerSeconSquar" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ACC_zul_Regelabw_oben : 35|5@1+ (0.0625,0) [0|1.9375] "Unit_MeterPerSeconSquar" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ACC_neg_Sollbeschl_Grad_02 : 40|8@1+ (0.05,0) [0|12.75] "Unit_MeterPerCubicSecon" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ACC_pos_Sollbeschl_Grad_02 : 48|8@1+ (0.05,0) [0|12.75] "Unit_MeterPerCubicSecon" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ACC_Anfahren : 56|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ACC_Anhalten : 57|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ACC_Typ : 58|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ACC_Status_ACC : 60|3@1+ (1,0) [0|7] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ACC_Minimale_Bremsung : 63|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB BO_ 279 ACC_10: 8 Gateway_MQB - SG_ ACC_10_CRC : 0|8@1+ (1,0) [0|255] "" Airbag_MQB - SG_ ACC_10_BZ : 8|4@1+ (1,0) [0|15] "" Airbag_MQB - SG_ AWV1_Anf_Prefill : 16|1@1+ (1,0) [0|1] "" Airbag_MQB + SG_ ACC_10_CRC : 0|8@1+ (1,0) [0|255] "" Airbag_MQB + SG_ ACC_10_BZ : 8|4@1+ (1,0) [0|15] "" Airbag_MQB + SG_ AWV1_Anf_Prefill : 16|1@1+ (1,0) [0|1] "" Airbag_MQB SG_ ANB_CM_Info : 17|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ AWV2_Freigabe : 18|1@1+ (1,0) [0|1] "" Airbag_MQB + SG_ AWV2_Freigabe : 18|1@1+ (1,0) [0|1] "" Airbag_MQB SG_ AWV1_HBA_Param : 19|2@1+ (1,0) [0|3] "" Vector__XXX SG_ AWV2_Ruckprofil : 21|3@1+ (1,0) [0|7] "" Vector__XXX SG_ AWV2_Priowarnung : 24|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ ANB_CM_Anforderung : 25|1@1+ (1,0) [0|1] "" Airbag_MQB + SG_ ANB_CM_Anforderung : 25|1@1+ (1,0) [0|1] "" Airbag_MQB SG_ ANB_Info_Teilbremsung : 26|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ANB_Notfallblinken : 27|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ ANB_Teilbremsung_Freigabe : 28|1@1+ (1,0) [0|1] "" Airbag_MQB - SG_ ANB_Zielbrems_Teilbrems_Verz_Anf : 29|10@1+ (0.024,-20.016) [-20.016|4.536] "Unit_MeterPerSeconSquar" Airbag_MQB - SG_ ANB_Zielbremsung_Freigabe : 39|1@1+ (1,0) [0|1] "" Airbag_MQB + SG_ ANB_Teilbremsung_Freigabe : 28|1@1+ (1,0) [0|1] "" Airbag_MQB + SG_ ANB_Zielbrems_Teilbrems_Verz_Anf : 29|10@1+ (0.024,-20.016) [-20.016|4.536] "Unit_MeterPerSeconSquar" Airbag_MQB + SG_ ANB_Zielbremsung_Freigabe : 39|1@1+ (1,0) [0|1] "" Airbag_MQB SG_ AWV_Vorstufe : 40|1@1+ (1,0) [0|1] "" Vector__XXX SG_ AWV_Halten : 41|1@1+ (1,0) [0|1] "" Vector__XXX BO_ 64 Airbag_01: 8 Airbag_MQB - SG_ Airbag_01_CRC : 0|8@1+ (1,0) [0|255] "" BMS_MQB,Gateway_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ Airbag_01_BZ : 8|4@1+ (1,0) [0|15] "" BMS_MQB,Gateway_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ AB_RGS_Anst : 12|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ AB_Front_Crash : 16|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ AB_Heck_Crash : 17|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ AB_SF_Crash : 18|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ AB_SB_Crash : 19|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ AB_Rollover_Crash : 20|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ AB_Crash_Int : 21|3@1+ (1,0) [0|7] "" BMS_MQB,Gateway_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ AB_Lampe : 24|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ AB_Deaktiviert : 25|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ AB_VB_deaktiviert : 26|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ AB_Systemfehler : 27|1@1+ (1,0) [0|1] "" BMS_MQB,Gateway_MQB,LEH_MQB - SG_ AB_Diagnose : 28|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ AB_Stellgliedtest : 29|1@1+ (1,0) [0|1] "" BMS_MQB,Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ AB_Erh_Auf_VB : 30|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ AB_Gurtwarn_VF : 32|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ AB_Gurtwarn_VB : 33|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ AB_Anzeige_Fussg : 34|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ AB_Texte_AKS : 36|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ AB_PAO_Leuchte_Anf : 38|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ AB_MKB_gueltig : 39|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ AB_MKB_Anforderung : 40|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ AB_Versorgungsspannung : 41|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ Airbag_01_CRC : 0|8@1+ (1,0) [0|255] "" BMS_MQB,Gateway_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ Airbag_01_BZ : 8|4@1+ (1,0) [0|15] "" BMS_MQB,Gateway_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ AB_RGS_Anst : 12|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ AB_Front_Crash : 16|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ AB_Heck_Crash : 17|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ AB_SF_Crash : 18|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ AB_SB_Crash : 19|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ AB_Rollover_Crash : 20|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ AB_Crash_Int : 21|3@1+ (1,0) [0|7] "" BMS_MQB,Gateway_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ AB_Lampe : 24|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ AB_Deaktiviert : 25|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ AB_VB_deaktiviert : 26|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ AB_Systemfehler : 27|1@1+ (1,0) [0|1] "" BMS_MQB,Gateway_MQB,LEH_MQB + SG_ AB_Diagnose : 28|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ AB_Stellgliedtest : 29|1@1+ (1,0) [0|1] "" BMS_MQB,Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ AB_Erh_Auf_VB : 30|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ AB_Gurtwarn_VF : 32|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ AB_Gurtwarn_VB : 33|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ AB_Anzeige_Fussg : 34|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ AB_Texte_AKS : 36|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ AB_PAO_Leuchte_Anf : 38|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ AB_MKB_gueltig : 39|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ AB_MKB_Anforderung : 40|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ AB_Versorgungsspannung : 41|1@1+ (1,0) [0|1] "" Gateway_MQB BO_ 1312 Airbag_02: 8 Airbag_MQB - SG_ AB_Belegung_VB : 26|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ AB_Gurtschloss_FA : 40|2@1+ (1,0) [0|3] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Otto_MQB - SG_ AB_Gurtschloss_BF : 42|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ AB_Gurtschloss_Reihe2_FA : 44|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ AB_Gurtschloss_Reihe2_MI : 46|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ AB_Gurtschloss_Reihe2_BF : 48|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ AB_Gurtschloss_Reihe3_FA : 50|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ AB_Gurtschloss_Reihe3_MI : 52|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ AB_Gurtschloss_Reihe3_BF : 54|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ AB_Sitzpos_Sens_FA : 56|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ AB_Sitzpos_Sens_BF : 58|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ AB_Belegung_VB : 26|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ AB_Gurtschloss_FA : 40|2@1+ (1,0) [0|3] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Otto_MQB + SG_ AB_Gurtschloss_BF : 42|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ AB_Gurtschloss_Reihe2_FA : 44|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ AB_Gurtschloss_Reihe2_MI : 46|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ AB_Gurtschloss_Reihe2_BF : 48|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ AB_Gurtschloss_Reihe3_FA : 50|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ AB_Gurtschloss_Reihe3_MI : 52|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ AB_Gurtschloss_Reihe3_BF : 54|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ AB_Sitzpos_Sens_FA : 56|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ AB_Sitzpos_Sens_BF : 58|2@1+ (1,0) [0|3] "" Gateway_MQB BO_ 65 Airbag_03: 8 Airbag_MQB - SG_ Airbag_03_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB - SG_ Airbag_03_BZ : 8|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ AB_MKB_Safing : 63|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ Airbag_03_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB + SG_ Airbag_03_BZ : 8|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ AB_MKB_Safing : 63|1@1+ (1,0) [0|1] "" Gateway_MQB BO_ 1633 Anhaenger_01: 8 Gateway_MQB - SG_ AAG_BZ : 0|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ AAG_Bremsl_durch_ECD : 5|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ AAG_BZ : 0|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ AAG_Bremsl_durch_ECD : 5|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ AAG_Anhaenger_abgesteckt : 6|1@1+ (1,0) [0|1] "" Vector__XXX SG_ AAG_NSL_aktiv : 7|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ AAG_Anhaenger_erkannt : 8|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ AAG_Anhaenger_erkannt : 8|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ AAG_Blinker_H_aktiv : 9|1@1+ (1,0) [0|1] "" Vector__XXX SG_ AAG_Blinker_HL_def : 10|1@1+ (1,0) [0|1] "" Vector__XXX SG_ AAG_Blinker_HR_def : 11|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ AAG_Bremslicht_H_def : 12|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ AAG_Bremslicht_H_def : 12|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ AAG_Schlusslicht_HL_def : 13|1@1+ (1,0) [0|1] "" Vector__XXX SG_ AAG_Schlusslicht_HR_def : 14|1@1+ (1,0) [0|1] "" Vector__XXX SG_ AAG_AVS_Fehler_02 : 18|1@1+ (1,0) [0|1] "" Vector__XXX @@ -134,99 +134,99 @@ BO_ 1626 BCM_01: 8 Gateway_MQB SG_ BCM_Bremsfluessigkeit_Sensor : 13|1@1+ (1,0) [0|1] "" Vector__XXX SG_ BCM1_Licht_Warn : 14|1@1+ (1,0) [0|1] "" Vector__XXX SG_ BCM_Waschwasser_Sensor : 15|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ BCM_Kuehlmittel_Sensor : 16|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ BCM_Kuehlmittel_Sensor : 16|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB SG_ BCM1_Kl_15_HW_erkannt : 17|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ BCM_Eis_Offroad_Taste : 18|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Otto_MQB + SG_ BCM_Eis_Offroad_Taste : 18|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Otto_MQB SG_ ZZH_Endlage_oben : 19|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ZZH_Endlage_unten : 20|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ZZH_Endlage_unplausibel : 21|1@1+ (1,0) [0|1] "" Vector__XXX SG_ BCM2_EZS_gedrueckt : 22|1@1+ (1,0) [0|1] "" Vector__XXX SG_ BCM2_SST_gedrueckt : 23|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ BCM_Hybrid_StartStopp_Taste : 24|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BCM_Hybrid_StartStopp_Taste : 24|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ BCM1_Warnblink_Taster : 25|1@1+ (1,0) [0|1] "" Vector__XXX SG_ BCM1_Valet_Parking_Taster : 26|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ BCM_Remotestart_Betrieb : 27|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ BCM_Remotestart_Betrieb : 27|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB SG_ BCM1_HSK_Taster : 28|1@1+ (1,0) [0|1] "" Vector__XXX SG_ BCM1_Heckrollo_Taster : 29|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ BCM1_Rueckfahrlicht_Schalter : 30|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ BCM1_MH_Schalter : 31|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB - SG_ BCM1_MH_WIV_Schalter : 32|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ BCM_Eco_Charisma_Taste : 33|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ BCM_Thermomanagement : 34|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ BCM_Thermomanagement_Fehler : 36|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ BCM_Thermomanagement_gueltig : 37|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BCM1_Rueckfahrlicht_Schalter : 30|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BCM1_MH_Schalter : 31|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ BCM1_MH_WIV_Schalter : 32|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BCM_Eco_Charisma_Taste : 33|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ BCM_Thermomanagement : 34|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BCM_Thermomanagement_Fehler : 36|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BCM_Thermomanagement_gueltig : 37|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ BCM1_Lichtwarn_Texte : 38|2@1+ (1,0) [0|3] "" Vector__XXX BO_ 869 BEM_05: 8 Gateway_MQB - SG_ BEM_P_Generator : 16|8@1+ (50,0) [0|12700] "Unit_Watt" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ BEM_n_LLA : 24|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ BEM_01_Abschaltstufen : 26|3@1+ (1,0) [0|7] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ BEM_Anf_KL : 29|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ BEM_StartStopp_Info : 30|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB - SG_ BEM_DFM : 32|5@1+ (3.225,0.025) [0.025|100] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ BEM_EMLIN_ungueltig : 37|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ BEM_Batt_Ab : 38|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ BEM_Segel_Info : 48|2@1+ (1,0) [0|3] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ BEM_HYB_DC_uSollLV : 50|6@1+ (0.1,10.6) [10.6|16] "Unit_Volt" LEH_MQB - SG_ BEM_HYB_DC_uMinLV : 56|8@1+ (0.1,0) [0|25.3] "Unit_Volt" LEH_MQB + SG_ BEM_P_Generator : 16|8@1+ (50,0) [0|12700] "Unit_Watt" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BEM_n_LLA : 24|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BEM_01_Abschaltstufen : 26|3@1+ (1,0) [0|7] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BEM_Anf_KL : 29|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BEM_StartStopp_Info : 30|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ BEM_DFM : 32|5@1+ (3.225,0.025) [0.025|100] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BEM_EMLIN_ungueltig : 37|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BEM_Batt_Ab : 38|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BEM_Segel_Info : 48|2@1+ (1,0) [0|3] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BEM_HYB_DC_uSollLV : 50|6@1+ (0.1,10.6) [10.6|16] "Unit_Volt" LEH_MQB + SG_ BEM_HYB_DC_uMinLV : 56|8@1+ (0.1,0) [0|25.3] "Unit_Volt" LEH_MQB BO_ 1628 BMS_Hybrid_01: 8 BMS_MQB - SG_ BMS_HYB_ASV_hinten_Status : 13|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ BMS_HYB_ASV_vorne_Status : 14|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ BMS_HYB_KD_Fehler : 15|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ BMS_HYB_BattFanSpd : 16|4@1+ (10,0) [0|100] "Unit_PerCent" Gateway_MQB - SG_ BMS_HYB_VentilationReq : 20|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ BMS_HYB_Spuelbetrieb_Status : 21|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ BMS_HYB_Kuehlung_Anf : 22|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ BMS_HYB_Temp_vor_Verd : 24|8@1+ (0.5,-40) [-40|86.5] "Unit_DegreCelsi" Gateway_MQB - SG_ BMS_HYB_Temp_nach_Verd : 32|8@1+ (0.5,-40) [-40|86.5] "Unit_DegreCelsi" Gateway_MQB - SG_ BMS_Temperatur : 40|8@1+ (0.5,-40) [-40|86.5] "Unit_DegreCelsi" Gateway_MQB - SG_ BMS_Temperatur_Ansaugluft : 48|8@1+ (0.5,-40) [-40|86.5] "Unit_DegreCelsi" Gateway_MQB - SG_ BMS_IstSpannung_HV : 56|8@1+ (1,100) [100|350] "Unit_Volt" Gateway_MQB + SG_ BMS_HYB_ASV_hinten_Status : 13|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ BMS_HYB_ASV_vorne_Status : 14|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ BMS_HYB_KD_Fehler : 15|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ BMS_HYB_BattFanSpd : 16|4@1+ (10,0) [0|100] "Unit_PerCent" Gateway_MQB + SG_ BMS_HYB_VentilationReq : 20|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ BMS_HYB_Spuelbetrieb_Status : 21|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ BMS_HYB_Kuehlung_Anf : 22|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ BMS_HYB_Temp_vor_Verd : 24|8@1+ (0.5,-40) [-40|86.5] "Unit_DegreCelsi" Gateway_MQB + SG_ BMS_HYB_Temp_nach_Verd : 32|8@1+ (0.5,-40) [-40|86.5] "Unit_DegreCelsi" Gateway_MQB + SG_ BMS_Temperatur : 40|8@1+ (0.5,-40) [-40|86.5] "Unit_DegreCelsi" Gateway_MQB + SG_ BMS_Temperatur_Ansaugluft : 48|8@1+ (0.5,-40) [-40|86.5] "Unit_DegreCelsi" Gateway_MQB + SG_ BMS_IstSpannung_HV : 56|8@1+ (1,100) [100|350] "Unit_Volt" Gateway_MQB BO_ 901 Charisma_01: 8 Gateway_MQB SG_ CHA_Ziel_FahrPr_ALR : 0|4@1+ (1,0) [0|15] "" Vector__XXX SG_ CHA_Ziel_FahrPr_ESP : 4|4@1+ (1,0) [0|15] "" Vector__XXX SG_ CHA_Ziel_FahrPr_FL : 8|4@1+ (1,0) [0|15] "" Vector__XXX - SG_ CHA_Fahrer_Umschaltung : 14|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB - SG_ CHA_Ziel_FahrPr_MO : 16|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ CHA_Ziel_FahrPr_GE : 20|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ CHA_Fahrer_Umschaltung : 14|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB + SG_ CHA_Ziel_FahrPr_MO : 16|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ CHA_Ziel_FahrPr_GE : 20|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB SG_ CHA_Ziel_FahrPr_ST : 24|4@1+ (1,0) [0|15] "" Vector__XXX SG_ CHA_Ziel_FahrPr_SCU : 28|4@1+ (1,0) [0|15] "" Vector__XXX SG_ CHA_Ziel_FahrPr_DR : 32|4@1+ (1,0) [0|15] "" Vector__XXX SG_ CHA_Ziel_FahrPr_QS : 36|4@1+ (1,0) [0|15] "" Vector__XXX SG_ CHA_Ziel_FahrPr_AFS : 40|4@1+ (1,0) [0|15] "" Vector__XXX - SG_ CHA_Ziel_FahrPr_RGS : 44|4@1+ (1,0) [0|15] "" Airbag_MQB + SG_ CHA_Ziel_FahrPr_RGS : 44|4@1+ (1,0) [0|15] "" Airbag_MQB SG_ CHA_Ziel_FahrPr_EPS : 48|4@1+ (1,0) [0|15] "" Vector__XXX SG_ CHA_Ziel_FahrPr_ACC : 52|4@1+ (1,0) [0|15] "" Vector__XXX - SG_ CHA_Ziel_FahrPr_SAK : 56|4@1+ (1,0) [0|15] "" SAK_MQB + SG_ CHA_Ziel_FahrPr_SAK : 56|4@1+ (1,0) [0|15] "" SAK_MQB SG_ CHA_Ziel_FahrPr_MStSt : 60|4@1+ (1,0) [0|15] "" Vector__XXX BO_ 945 DC_Hybrid_01: 8 LEH_MQB - SG_ DC_HYB_iAktLV : 12|10@1+ (1,-511) [-511|510] "Unit_Amper" Gateway_MQB - SG_ DC_HYB_iAktReserveLV : 22|10@1+ (1,-511) [-511|510] "Unit_Amper" Gateway_MQB - SG_ DC_HYB_uAktLV : 32|8@1+ (0.1,0) [0|25.3] "Unit_Volt" Gateway_MQB - SG_ DC_HYB_LangsRegelung : 40|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ DC_HYB_Abregelung_Temperatur : 41|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ DC_HYB_Fehler_RedLeistung : 42|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ DC_HYB_Fehler_intern : 43|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ DC_HYB_Fehler_Spannung : 44|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ DC_HYB_Auslastungsgrad : 56|8@1+ (0.4,0) [0|100] "Unit_PerCent" Gateway_MQB + SG_ DC_HYB_iAktLV : 12|10@1+ (1,-511) [-511|510] "Unit_Amper" Gateway_MQB + SG_ DC_HYB_iAktReserveLV : 22|10@1+ (1,-511) [-511|510] "Unit_Amper" Gateway_MQB + SG_ DC_HYB_uAktLV : 32|8@1+ (0.1,0) [0|25.3] "Unit_Volt" Gateway_MQB + SG_ DC_HYB_LangsRegelung : 40|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ DC_HYB_Abregelung_Temperatur : 41|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ DC_HYB_Fehler_RedLeistung : 42|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ DC_HYB_Fehler_intern : 43|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ DC_HYB_Fehler_Spannung : 44|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ DC_HYB_Auslastungsgrad : 56|8@1+ (0.4,0) [0|100] "Unit_PerCent" Gateway_MQB BO_ 1714 Diagnose_01: 8 Gateway_MQB - SG_ DGN_Verlernzaehler : 0|8@1+ (1,0) [0|254] "" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,SAK_MQB - SG_ KBI_Kilometerstand : 8|20@1+ (1,0) [0|1048573] "Unit_KiloMeter" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB - SG_ UH_Jahr : 28|7@1+ (1,2000) [2000|2127] "Unit_Year" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB - SG_ UH_Monat : 35|4@1+ (1,0) [1|12] "Unit_Month" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB - SG_ UH_Tag : 39|5@1+ (1,0) [1|31] "Unit_Day" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB - SG_ UH_Stunde : 44|5@1+ (1,0) [0|23] "Unit_Hours" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB - SG_ UH_Minute : 49|6@1+ (1,0) [0|59] "Unit_Minut" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB - SG_ UH_Sekunde : 55|6@1+ (1,0) [0|59] "Unit_Secon" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB - SG_ Kombi_02_alt : 62|1@1+ (1,0) [0|1] "" Airbag_MQB,BMS_MQB,LEH_MQB - SG_ Uhrzeit_01_alt : 63|1@1+ (1,0) [0|1] "" Airbag_MQB,BMS_MQB,LEH_MQB + SG_ DGN_Verlernzaehler : 0|8@1+ (1,0) [0|254] "" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,SAK_MQB + SG_ KBI_Kilometerstand : 8|20@1+ (1,0) [0|1048573] "Unit_KiloMeter" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB + SG_ UH_Jahr : 28|7@1+ (1,2000) [2000|2127] "Unit_Year" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB + SG_ UH_Monat : 35|4@1+ (1,0) [1|12] "Unit_Month" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB + SG_ UH_Tag : 39|5@1+ (1,0) [1|31] "Unit_Day" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB + SG_ UH_Stunde : 44|5@1+ (1,0) [0|23] "Unit_Hours" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB + SG_ UH_Minute : 49|6@1+ (1,0) [0|59] "Unit_Minut" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB + SG_ UH_Sekunde : 55|6@1+ (1,0) [0|59] "Unit_Secon" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB + SG_ Kombi_02_alt : 62|1@1+ (1,0) [0|1] "" Airbag_MQB,BMS_MQB,LEH_MQB + SG_ Uhrzeit_01_alt : 63|1@1+ (1,0) [0|1] "" Airbag_MQB,BMS_MQB,LEH_MQB BO_ 1520 Dimmung_01: 8 Gateway_MQB - SG_ DI_KL_58xd : 0|8@1+ (1,0) [0|253] "" Airbag_MQB + SG_ DI_KL_58xd : 0|8@1+ (1,0) [0|253] "" Airbag_MQB SG_ DI_KL_58xs : 8|7@1+ (1,0) [0|100] "Unit_PerCent" Vector__XXX SG_ DI_Display_Nachtdesign : 15|1@1+ (1,0) [0|1] "" Vector__XXX SG_ DI_KL_58xt : 16|7@1+ (1,0) [0|100] "Unit_PerCent" Vector__XXX @@ -235,7 +235,7 @@ BO_ 1520 Dimmung_01: 8 Gateway_MQB BO_ 1603 Einheiten_01: 8 Gateway_MQB SG_ KBI_Einheit_Datum : 0|2@1+ (1,0) [0|3] "" Vector__XXX SG_ KBI_Einheit_Druck : 2|2@1+ (1,0) [0|3] "" Vector__XXX - SG_ KBI_Einheit_Streckenanz : 4|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB + SG_ KBI_Einheit_Streckenanz : 4|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB SG_ KBI_MFA_v_Einheit_02 : 5|1@1+ (1,0) [0|1] "" Vector__XXX SG_ KBI_Einheit_Temp : 6|1@1+ (1,0) [0|1] "" Vector__XXX SG_ KBI_Einheit_Uhrzeit : 7|1@1+ (1,0) [0|1] "" Vector__XXX @@ -244,171 +244,171 @@ BO_ 1603 Einheiten_01: 8 Gateway_MQB SG_ KBI_Einheit_Sprache : 16|8@1+ (1,0) [0|255] "" Vector__XXX BO_ 260 EPB_01: 8 Gateway_MQB - SG_ EPB_01_CRC : 0|8@1+ (1,0) [0|255] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ EPB_01_BZ : 8|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ EPB_01_CRC : 0|8@1+ (1,0) [0|255] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ EPB_01_BZ : 8|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ EPB_QBit_Laengsbeschleunigung : 12|1@1+ (1,0) [0|1] "" Vector__XXX SG_ EPB_QBit_Pedalweg_Kuppl : 13|1@1+ (1,0) [0|1] "" Vector__XXX SG_ EPB_BCM2_Motor_Wakeup : 14|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ EPB_Freig_Verzoeg_Anf : 15|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ EPB_Freig_Verzoeg_Anf : 15|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ EPB_Verzoeg_Anf : 16|8@1+ (0.048,-7.968) [-7.968|4.224] "Unit_MeterPerSeconSquar" Vector__XXX SG_ EPB_Laengsbeschleunigung : 24|8@1+ (1,-128) [-128|126] "Unit_PerCentOfForceOfGravi" Vector__XXX SG_ EPB_Pedalweg_Kuppl : 32|8@1+ (0.4,0) [8|92] "Unit_PerCent" Vector__XXX SG_ EPB_Anfahrwunsch_erkannt : 48|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ EPB_DAA_Randbed_erf : 49|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ EPB_DAA_Randbed_erf : 49|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB SG_ EPB_Fehlerstatus : 50|2@1+ (1,0) [0|3] "" Vector__XXX - SG_ EPB_Schalterposition : 52|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ EPB_QBit_Schalterpos : 54|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ EPB_Schalterposition : 52|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ EPB_QBit_Schalterpos : 54|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ EPB_Konsistenz_ACC : 55|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ EPB_Spannkraft : 56|5@1+ (1,0) [0|29] "Unit_KiloNewto" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ EPB_Status : 61|2@1+ (1,0) [0|3] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ EPB_Spannkraft : 56|5@1+ (1,0) [0|29] "Unit_KiloNewto" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ EPB_Status : 61|2@1+ (1,0) [0|3] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB BO_ 257 ESP_02: 8 Gateway_MQB - SG_ ESP_02_CRC : 0|8@1+ (1,0) [0|255] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_02_BZ : 8|4@1+ (1,0) [0|15] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_QBit_Gierrate : 12|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ ESP_QBit_Laengsbeschl : 13|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_QBit_Querb : 14|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_02_CRC : 0|8@1+ (1,0) [0|255] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_02_BZ : 8|4@1+ (1,0) [0|15] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_QBit_Gierrate : 12|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ ESP_QBit_Laengsbeschl : 13|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_QBit_Querb : 14|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ ESP_Stillstandsflag : 15|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ ESP_Querbeschleunigung : 16|8@1+ (0.01,-1.27) [-1.27|1.27] "Unit_ForceOfGravi" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Laengsbeschl : 24|10@1+ (0.03125,-16) [-16|15.90625] "Unit_MeterPerSeconSquar" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Querbeschleunigung : 16|8@1+ (0.01,-1.27) [-1.27|1.27] "Unit_ForceOfGravi" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Laengsbeschl : 24|10@1+ (0.03125,-16) [-16|15.90625] "Unit_MeterPerSeconSquar" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ ESP_Verteil_Wankmom : 34|5@1+ (0.1,-1) [-1|1] "" Vector__XXX SG_ ESP_QBit_Anf_Vert_Wank : 39|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ ESP_Gierrate : 40|14@1+ (0.01,0) [0|163.82] "Unit_DegreOfArcPerSecon" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ ESP_VZ_Gierrate : 54|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ ESP_Notbremsanzeige : 55|1@1+ (1,0) [0|1] "" Airbag_MQB + SG_ ESP_Gierrate : 40|14@1+ (0.01,0) [0|163.82] "Unit_DegreOfArcPerSecon" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ ESP_VZ_Gierrate : 54|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ ESP_Notbremsanzeige : 55|1@1+ (1,0) [0|1] "" Airbag_MQB SG_ ESP_SpannungsAnf : 56|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ESP_PLA_Abbruch : 57|3@1+ (1,0) [0|7] "" Vector__XXX - SG_ ESP_Status_ESP_PLA : 60|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ ESP_Status_ESP_PLA : 60|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB BO_ 262 ESP_05: 8 Gateway_MQB - SG_ ESP_05_CRC : 0|8@1+ (1,0) [0|255] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_05_BZ : 8|4@1+ (1,0) [0|15] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_QBit_Bremsdruck : 12|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_QBit_Fahrer_bremst : 13|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Schwelle_Unterdruck : 14|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Bremsdruck : 16|10@1+ (0.3,-30) [-30|276.6] "Unit_Bar" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Fahrer_bremst : 26|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Verz_TSK_aktiv : 27|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Lenkeingriff_ADS : 28|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Konsistenz_TSK : 29|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Bremsruck_AWV2 : 30|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_05_CRC : 0|8@1+ (1,0) [0|255] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_05_BZ : 8|4@1+ (1,0) [0|15] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_QBit_Bremsdruck : 12|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_QBit_Fahrer_bremst : 13|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Schwelle_Unterdruck : 14|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Bremsdruck : 16|10@1+ (0.3,-30) [-30|276.6] "Unit_Bar" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Fahrer_bremst : 26|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Verz_TSK_aktiv : 27|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Lenkeingriff_ADS : 28|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Konsistenz_TSK : 29|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Bremsruck_AWV2 : 30|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ ESP_Konsistenz_AWV2 : 31|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ ECD_Fehler : 32|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ECD_nicht_verfuegbar : 33|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Status_Bremsentemp : 34|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ECD_Fehler : 32|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ECD_nicht_verfuegbar : 33|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Status_Bremsentemp : 34|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ ESP_Autohold_Standby : 35|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ ESP_HDC_Standby : 36|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ ESP_HDC_Standby : 36|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB SG_ ESP_HBA_aktiv : 37|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ ESP_Prefill_ausgeloest : 38|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Prefill_ausgeloest : 38|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ ESP_Rueckwaertsfahrt_erkannt : 39|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ ESP_Status_Anfahrhilfe : 40|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_HDC_aktiv : 41|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ ESP_StartStopp_Info : 42|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ ESP_Status_Anfahrhilfe : 40|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_HDC_aktiv : 41|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ ESP_StartStopp_Info : 42|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB SG_ ESP_Eingr_HL : 44|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ESP_Eingr_HR : 45|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ESP_Eingr_VL : 46|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ESP_Eingr_VR : 47|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ ESP_BKV_Unterdruck : 48|8@1+ (4,0) [0|1012] "Unit_MilliBar" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Autohold_aktiv : 56|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_FStatus_Anfahrhilfe : 57|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ ESP_BKV_Unterdruck : 48|8@1+ (4,0) [0|1012] "Unit_MilliBar" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Autohold_aktiv : 56|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_FStatus_Anfahrhilfe : 57|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB SG_ ESP_Verz_EPB_aktiv : 58|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ ECD_Bremslicht : 59|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ECD_Bremslicht : 59|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ ESP_Verzoeg_EPB_verf : 60|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ ESP_Status_Bremsdruck : 61|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Status_Bremsdruck : 61|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ ESP_Anforderung_EPB : 62|2@1+ (1,0) [0|3] "" Vector__XXX BO_ 914 ESP_07: 8 Gateway_MQB - SG_ ESP_07_CRC : 0|8@1+ (1,0) [0|255] "" Airbag_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_07_BZ : 8|4@1+ (1,0) [0|15] "" Airbag_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_07_CRC : 0|8@1+ (1,0) [0|255] "" Airbag_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_07_BZ : 8|4@1+ (1,0) [0|15] "" Airbag_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ ESP_ACC_LDE : 12|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ESP_Quattro_Antrieb : 13|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ESP_Codierung_ADS : 14|2@1+ (1,0) [0|3] "" Vector__XXX SG_ ESP_RTA_HL : 16|8@1+ (0.048828125,-6.20117) [-6.20117|6.152345625] "Unit_PerCent" Vector__XXX SG_ ESP_RTA_HR : 24|8@1+ (0.048828125,-6.20117) [-6.20117|6.152345625] "Unit_PerCent" Vector__XXX SG_ ESP_RTA_VR : 32|8@1+ (0.048828125,-6.20117) [-6.20117|6.152345625] "Unit_PerCent" Vector__XXX - SG_ OBD_Fehler_Radsensor_HL : 40|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ OBD_Fehler_Radsensor_HR : 44|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ OBD_Fehler_Radsensor_VL : 48|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ OBD_Fehler_Radsensor_VR : 52|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ OBD_Fehler_Radsensor_HL : 40|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ OBD_Fehler_Radsensor_HR : 44|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ OBD_Fehler_Radsensor_VL : 48|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ OBD_Fehler_Radsensor_VR : 52|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ ESP_Qualifizierung_Antriebsart : 56|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ESP_Offroad_Modus : 57|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ ESP_MKB_ausloesbar : 58|1@1+ (1,0) [0|1] "" Airbag_MQB - SG_ ESP_MKB_Status : 59|1@1+ (1,0) [0|1] "" Airbag_MQB + SG_ ESP_MKB_ausloesbar : 58|1@1+ (1,0) [0|1] "" Airbag_MQB + SG_ ESP_MKB_Status : 59|1@1+ (1,0) [0|1] "" Airbag_MQB SG_ ESP_CM_Variante : 60|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ESP_OBD_Status : 61|1@1+ (1,0) [0|1] "" Vector__XXX BO_ 278 ESP_10: 8 Gateway_MQB - SG_ ESP_10_CRC : 0|8@1+ (1,0) [0|255] "" Airbag_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_10_BZ : 8|4@1+ (1,0) [0|15] "" Airbag_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_QBit_Wegimpuls_VL : 12|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_QBit_Wegimpuls_VR : 13|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_QBit_Wegimpuls_HL : 14|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_QBit_Wegimpuls_HR : 15|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Wegimpuls_VL : 16|10@1+ (1,0) [0|1000] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Wegimpuls_VR : 26|10@1+ (1,0) [0|1000] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Wegimpuls_HL : 36|10@1+ (1,0) [0|1000] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Wegimpuls_HR : 46|10@1+ (1,0) [0|1000] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_VL_Fahrtrichtung : 56|2@1+ (1,0) [0|3] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_VR_Fahrtrichtung : 58|2@1+ (1,0) [0|3] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_HL_Fahrtrichtung : 60|2@1+ (1,0) [0|3] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_HR_Fahrtrichtung : 62|2@1+ (1,0) [0|3] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_10_CRC : 0|8@1+ (1,0) [0|255] "" Airbag_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_10_BZ : 8|4@1+ (1,0) [0|15] "" Airbag_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_QBit_Wegimpuls_VL : 12|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_QBit_Wegimpuls_VR : 13|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_QBit_Wegimpuls_HL : 14|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_QBit_Wegimpuls_HR : 15|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Wegimpuls_VL : 16|10@1+ (1,0) [0|1000] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Wegimpuls_VR : 26|10@1+ (1,0) [0|1000] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Wegimpuls_HL : 36|10@1+ (1,0) [0|1000] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Wegimpuls_HR : 46|10@1+ (1,0) [0|1000] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_VL_Fahrtrichtung : 56|2@1+ (1,0) [0|3] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_VR_Fahrtrichtung : 58|2@1+ (1,0) [0|3] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_HL_Fahrtrichtung : 60|2@1+ (1,0) [0|3] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_HR_Fahrtrichtung : 62|2@1+ (1,0) [0|3] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB BO_ 178 ESP_19: 8 Gateway_MQB - SG_ ESP_HL_Radgeschw_02 : 0|16@1+ (0.0075,0) [0|491.49] "Unit_KiloMeterPerHour" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_HR_Radgeschw_02 : 16|16@1+ (0.0075,0) [0|491.49] "Unit_KiloMeterPerHour" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_VL_Radgeschw_02 : 32|16@1+ (0.0075,0) [0|491.49] "Unit_KiloMeterPerHour" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_VR_Radgeschw_02 : 48|16@1+ (0.0075,0) [0|491.49] "Unit_KiloMeterPerHour" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_HL_Radgeschw_02 : 0|16@1+ (0.0075,0) [0|491.49] "Unit_KiloMeterPerHour" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_HR_Radgeschw_02 : 16|16@1+ (0.0075,0) [0|491.49] "Unit_KiloMeterPerHour" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_VL_Radgeschw_02 : 32|16@1+ (0.0075,0) [0|491.49] "Unit_KiloMeterPerHour" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_VR_Radgeschw_02 : 48|16@1+ (0.0075,0) [0|491.49] "Unit_KiloMeterPerHour" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB BO_ 1629 ESP_20: 8 Gateway_MQB SG_ ESP_20_CRC : 0|8@1+ (1,0) [0|255] "" Vector__XXX SG_ ESP_20_BZ : 8|4@1+ (1,0) [0|15] "" Vector__XXX SG_ BR_Systemart : 12|2@1+ (1,0) [0|3] "" Vector__XXX - SG_ ESP_Zaehnezahl : 16|8@1+ (1,0) [0|255] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ ESP_Zaehnezahl : 16|8@1+ (1,0) [0|255] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB SG_ ESP_Charisma_FahrPr : 24|4@1+ (1,0) [0|15] "" Vector__XXX SG_ ESP_Charisma_Status : 28|2@1+ (1,0) [0|3] "" Vector__XXX - SG_ BR_QBit_Reifenumfang : 51|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ BR_Reifenumfang : 52|12@1+ (1,0) [0|4095] "Unit_MilliMeter" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ BR_QBit_Reifenumfang : 51|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ BR_Reifenumfang : 52|12@1+ (1,0) [0|4095] "Unit_MilliMeter" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB BO_ 253 ESP_21: 8 Gateway_MQB - SG_ ESP_21_CRC : 0|8@1+ (1,0) [0|255] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_21_BZ : 8|4@1+ (1,0) [0|15] "" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ BR_Eingriffsmoment : 12|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_v_Signal : 32|16@1+ (0.01,0) [0|655.32] "Unit_KiloMeterPerHour" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB - SG_ ASR_Tastung_passiv : 48|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Tastung_passiv : 49|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Systemstatus : 50|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ASR_Schalteingriff : 51|2@1+ (1,0) [0|3] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ ESP_Haltebestaetigung : 53|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_QBit_v_Signal : 55|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ABS_Bremsung : 56|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ASR_Anf : 57|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ MSR_Anf : 58|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ EBV_Eingriff : 59|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ EDS_Eingriff : 60|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Eingriff : 61|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_ASP : 62|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ ESP_Anhaltevorgang_ACC_aktiv : 63|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_21_CRC : 0|8@1+ (1,0) [0|255] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_21_BZ : 8|4@1+ (1,0) [0|15] "" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BR_Eingriffsmoment : 12|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_v_Signal : 32|16@1+ (0.01,0) [0|655.32] "Unit_KiloMeterPerHour" Airbag_MQB,BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB,SAK_MQB + SG_ ASR_Tastung_passiv : 48|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Tastung_passiv : 49|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Systemstatus : 50|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ASR_Schalteingriff : 51|2@1+ (1,0) [0|3] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ ESP_Haltebestaetigung : 53|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_QBit_v_Signal : 55|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ABS_Bremsung : 56|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ASR_Anf : 57|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ MSR_Anf : 58|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ EBV_Eingriff : 59|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ EDS_Eingriff : 60|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Eingriff : 61|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_ASP : 62|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ESP_Anhaltevorgang_ACC_aktiv : 63|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB BO_ 987 Gateway_72: 8 Gateway_MQB - SG_ BCM_01_alt : 0|1@1+ (1,0) [0|1] "" Airbag_MQB - SG_ SMLS_01_alt : 1|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB - SG_ ZV_02_alt : 2|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ Wischer_01_alt : 3|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ Anhaenger_01_alt : 4|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ Klima_Sensor_02_alt : 5|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ VSG_01_alt : 6|1@1+ (1,0) [0|1] "" Airbag_MQB + SG_ BCM_01_alt : 0|1@1+ (1,0) [0|1] "" Airbag_MQB + SG_ SMLS_01_alt : 1|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ ZV_02_alt : 2|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ Wischer_01_alt : 3|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ Anhaenger_01_alt : 4|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ Klima_Sensor_02_alt : 5|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ VSG_01_alt : 6|1@1+ (1,0) [0|1] "" Airbag_MQB SG_ Klima_01_alt : 7|1@1+ (1,0) [0|1] "" Vector__XXX SG_ WFS_01_alt : 8|1@1+ (1,0) [0|1] "" Vector__XXX SG_ Licht_Anf_01_alt : 9|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ZV_HFS_offen : 20|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ZV_HBFS_offen : 21|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ VS_VD_offen_ver : 22|1@1+ (1,0) [0|1] "" Airbag_MQB + SG_ VS_VD_offen_ver : 22|1@1+ (1,0) [0|1] "" Airbag_MQB SG_ VS_VD_zu_ver : 23|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ZV_BT_offen : 24|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ BCM1_Rueckfahrlicht_Schalter : 25|1@1+ (1,0) [0|1] "" Airbag_MQB - SG_ ZV_FT_offen : 26|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ Wischer_vorne_aktiv : 27|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ AAG_Anhaenger_erkannt : 28|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ BCM1_Rueckfahrlicht_Schalter : 25|1@1+ (1,0) [0|1] "" Airbag_MQB + SG_ ZV_FT_offen : 26|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ Wischer_vorne_aktiv : 27|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ AAG_Anhaenger_erkannt : 28|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB SG_ BCM1_MH_Schalter : 29|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ZV_HD_offen : 30|1@1+ (1,0) [0|1] "" Vector__XXX SG_ Waschen_vorne_aktiv : 31|1@1+ (1,0) [0|1] "" Vector__XXX @@ -417,151 +417,151 @@ BO_ 987 Gateway_72: 8 Gateway_MQB SG_ BCM1_RFahrlicht_Fzg_Anf : 38|1@1+ (1,0) [0|1] "" Vector__XXX SG_ BCM1_RFahrlicht_Ahg_Anf : 39|1@1+ (1,0) [0|1] "" Vector__XXX SG_ BH_Fernlicht : 49|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ BH_Blinker_li : 50|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB - SG_ BH_Blinker_re : 51|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB - SG_ BCM1_OBD_FStatus_ATemp : 52|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ BCM1_Aussen_Temp_ungef : 56|8@1+ (0.5,-50) [-50|76] "Unit_DegreCelsi" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BH_Blinker_li : 50|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ BH_Blinker_re : 51|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ BCM1_OBD_FStatus_ATemp : 52|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BCM1_Aussen_Temp_ungef : 56|8@1+ (0.5,-50) [-50|76] "Unit_DegreCelsi" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB BO_ 989 Gateway_74: 8 Gateway_MQB - SG_ LH_EPS_01_alt : 0|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB - SG_ Kessy_04_alt : 1|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB - SG_ LIN_2_alt : 2|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MFG_01_alt : 3|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ LH_EPS_01_alt : 0|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB + SG_ Kessy_04_alt : 1|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ LIN_2_alt : 2|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MFG_01_alt : 3|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB SG_ GW_74_va_14 : 4|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ Klima_02_alt : 5|1@1+ (1,0) [0|1] "" BMS_MQB - SG_ Parkhilfe_01_alt : 6|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB - SG_ ELV_01_alt : 7|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ KY_StartStopp_Info : 16|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB - SG_ PH_StartStopp_Info : 18|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB - SG_ EPS_Lenkerposition : 20|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB - SG_ ELV_Anf_Klemme_50 : 22|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ MF_StartStopp_Info : 25|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB - SG_ KL_Geblaesespannung_Soll : 40|8@1+ (0.05,0.5) [2|13] "Unit_Volt" BMS_MQB + SG_ Klima_02_alt : 5|1@1+ (1,0) [0|1] "" BMS_MQB + SG_ Parkhilfe_01_alt : 6|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ ELV_01_alt : 7|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KY_StartStopp_Info : 16|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ PH_StartStopp_Info : 18|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ EPS_Lenkerposition : 20|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB + SG_ ELV_Anf_Klemme_50 : 22|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ MF_StartStopp_Info : 25|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ KL_Geblaesespannung_Soll : 40|8@1+ (0.05,0.5) [2|13] "Unit_Volt" BMS_MQB SG_ KL_Umluftklappe_Status : 48|4@1+ (1,0) [0|15] "" Vector__XXX - SG_ MFL_Tip_Down : 56|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MFL_Tip_Up : 57|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ LS_Tiptronic_Fehler : 58|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MFL_Tip_Down : 56|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MFL_Tip_Up : 57|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ LS_Tiptronic_Fehler : 58|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB BO_ 296 Getriebe_06: 3 Getriebe_DQ_Hybrid_MQB - SG_ GE_WH_Sperre : 0|1@1+ (1,0) [0|1] "" Waehlhebel_MQB - SG_ GE_Ausleuchtungsmode : 1|1@1+ (1,0) [0|1] "" Waehlhebel_MQB - SG_ GE_Test_Freigabe : 2|1@1+ (1,0) [0|1] "" Waehlhebel_MQB - SG_ GE_Ist_Fahrstufe : 4|4@1+ (1,0) [0|15] "" Waehlhebel_MQB - SG_ GE_Testparameter_1 : 8|8@1+ (1,0) [0|255] "" Waehlhebel_MQB - SG_ GE_Testparameter_2 : 16|8@1+ (1,0) [0|255] "" Waehlhebel_MQB + SG_ GE_WH_Sperre : 0|1@1+ (1,0) [0|1] "" Waehlhebel_MQB + SG_ GE_Ausleuchtungsmode : 1|1@1+ (1,0) [0|1] "" Waehlhebel_MQB + SG_ GE_Test_Freigabe : 2|1@1+ (1,0) [0|1] "" Waehlhebel_MQB + SG_ GE_Ist_Fahrstufe : 4|4@1+ (1,0) [0|15] "" Waehlhebel_MQB + SG_ GE_Testparameter_1 : 8|8@1+ (1,0) [0|255] "" Waehlhebel_MQB + SG_ GE_Testparameter_2 : 16|8@1+ (1,0) [0|255] "" Waehlhebel_MQB BO_ 173 Getriebe_11: 8 Getriebe_DQ_Hybrid_MQB - SG_ Getriebe_11_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ Getriebe_11_BZ : 8|4@1+ (1,0) [0|15] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_MMom_Soll_02 : 12|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_MMom_Vorhalt_02 : 22|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Uefkt : 32|10@1+ (0.1,0) [0|102.2] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Fahrstufe : 42|5@1+ (1,0) [0|31] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Schaltvorgang : 47|1@1+ (1,0) [0|1] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Status_Kupplung : 54|2@1+ (1,0) [0|3] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_MMom_Status : 56|2@1+ (1,0) [0|3] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Freig_MMom_Vorhalt : 58|1@1+ (1,0) [0|1] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Verbot_Ausblendung : 59|1@1+ (1,0) [0|1] "" Gateway_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Zielgang : 60|4@1+ (1,0) [0|15] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ Getriebe_11_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ Getriebe_11_BZ : 8|4@1+ (1,0) [0|15] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_MMom_Soll_02 : 12|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_MMom_Vorhalt_02 : 22|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Uefkt : 32|10@1+ (0.1,0) [0|102.2] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Fahrstufe : 42|5@1+ (1,0) [0|31] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Schaltvorgang : 47|1@1+ (1,0) [0|1] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Status_Kupplung : 54|2@1+ (1,0) [0|3] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_MMom_Status : 56|2@1+ (1,0) [0|3] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Freig_MMom_Vorhalt : 58|1@1+ (1,0) [0|1] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Verbot_Ausblendung : 59|1@1+ (1,0) [0|1] "" Gateway_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Zielgang : 60|4@1+ (1,0) [0|15] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB BO_ 174 Getriebe_12: 8 Getriebe_DQ_Hybrid_MQB - SG_ Getriebe_12_CRC : 0|8@1+ (1,0) [0|255] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ Getriebe_12_BZ : 8|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Drehzahlmesser_Daempfung : 12|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Schubabschalt_Unt : 13|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Freigabe_Synchro : 14|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Synchro_Wunschdrehz : 15|9@1+ (25,0) [0|12750] "Unit_MinutInver" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Synchro_Zeit : 24|8@1+ (20,0) [0|5080] "Unit_MilliSecon" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Mom_Begr_Gradient : 32|8@1+ (10,0) [0|2540] "Unit_NewtoMeterPerSecon" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Anheb_Solldrehz_Leerlauf : 40|8@1+ (10,0) [0|2540] "Unit_MinutInver" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Aufnahmemoment : 48|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ Getriebe_12_CRC : 0|8@1+ (1,0) [0|255] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ Getriebe_12_BZ : 8|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Drehzahlmesser_Daempfung : 12|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Schubabschalt_Unt : 13|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Freigabe_Synchro : 14|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Synchro_Wunschdrehz : 15|9@1+ (25,0) [0|12750] "Unit_MinutInver" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Synchro_Zeit : 24|8@1+ (20,0) [0|5080] "Unit_MilliSecon" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Mom_Begr_Gradient : 32|8@1+ (10,0) [0|2540] "Unit_NewtoMeterPerSecon" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Anheb_Solldrehz_Leerlauf : 40|8@1+ (10,0) [0|2540] "Unit_MinutInver" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Aufnahmemoment : 48|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ GE_Anf_Zylabsch : 58|2@1+ (1,0) [0|3] "" Vector__XXX - SG_ GE_HYB_DZ_Eingriff : 62|2@1+ (1,0) [0|3] "" Motor_Hybrid_MQB + SG_ GE_HYB_DZ_Eingriff : 62|2@1+ (1,0) [0|3] "" Motor_Hybrid_MQB BO_ 301 Getriebe_13: 8 Getriebe_DQ_Hybrid_MQB - SG_ Getriebe_13_CRC : 0|8@1+ (1,0) [0|255] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ Getriebe_13_BZ : 8|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_StartStopp_Info : 12|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB - SG_ GE_Langfr_Schutzmom_02 : 14|9@1+ (1,0) [0|509] "Unit_NewtoMeter" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Eingangsdrehz : 48|14@1+ (1,0) [0|16381] "Unit_MinutInver" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Notlauf : 62|1@1+ (1,0) [0|1] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Freig_Langfr_Schutzmom : 63|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ Getriebe_13_CRC : 0|8@1+ (1,0) [0|255] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ Getriebe_13_BZ : 8|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_StartStopp_Info : 12|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ GE_Langfr_Schutzmom_02 : 14|9@1+ (1,0) [0|509] "Unit_NewtoMeter" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Eingangsdrehz : 48|14@1+ (1,0) [0|16381] "Unit_MinutInver" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Notlauf : 62|1@1+ (1,0) [0|1] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Freig_Langfr_Schutzmom : 63|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB BO_ 968 Getriebe_14: 8 Getriebe_DQ_Hybrid_MQB - SG_ GE_OBD_AbsperrVent : 12|4@1+ (1,0) [0|15] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_amax_moeglich : 16|9@1+ (0.024,-2.016) [-2.016|10.224] "Unit_MeterPerSeconSquar" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Charisma_FahrPr : 25|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ GE_Charisma_Status : 29|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ GE_Verlustmoment : 32|8@1+ (1,0) [0|254] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Freigabe_Verfallsinfo_WFS : 49|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ GE_Codierung_MSG : 50|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ GE_LaunchControl : 51|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ GE_Heizwunsch : 52|2@1+ (1,0) [0|3] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_OBD_Status : 54|1@1+ (1,0) [0|1] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_LFR_Adaption : 55|1@1+ (1,0) [0|1] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GE_Sumpftemperatur : 56|8@1+ (1,-58) [-58|196] "Unit_DegreCelsi" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_OBD_AbsperrVent : 12|4@1+ (1,0) [0|15] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_amax_moeglich : 16|9@1+ (0.024,-2.016) [-2.016|10.224] "Unit_MeterPerSeconSquar" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Charisma_FahrPr : 25|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ GE_Charisma_Status : 29|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ GE_Verlustmoment : 32|8@1+ (1,0) [0|254] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Freigabe_Verfallsinfo_WFS : 49|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ GE_Codierung_MSG : 50|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ GE_LaunchControl : 51|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ GE_Heizwunsch : 52|2@1+ (1,0) [0|3] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_OBD_Status : 54|1@1+ (1,0) [0|1] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_LFR_Adaption : 55|1@1+ (1,0) [0|1] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GE_Sumpftemperatur : 56|8@1+ (1,-58) [-58|196] "Unit_DegreCelsi" Gateway_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB BO_ 158 Getriebe_Hybrid_01: 8 Getriebe_DQ_Hybrid_MQB - SG_ Getriebe_Hybrid_01_CRC : 0|8@1+ (1,0) [0|255] "" Motor_Hybrid_MQB - SG_ Getriebe_Hybrid_01_BZ : 8|4@1+ (1,0) [0|15] "" Motor_Hybrid_MQB - SG_ GE_HYB_Fehlerstatus : 12|2@1+ (1,0) [0|3] "" Motor_Hybrid_MQB - SG_ GE_HYB_Freigabe_K0 : 16|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB - SG_ GE_HYB_Freigabe_LL_Reg : 17|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB - SG_ GE_HYB_Freig_sSchl_K0 : 18|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB - SG_ GE_HYB_Freig_VM_EM_Stop : 19|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB - SG_ GE_HYB_Wiederstart : 20|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB - SG_ GE_HYB_Filt_MomAufbau : 21|3@1+ (1,0) [0|7] "" Motor_Hybrid_MQB + SG_ Getriebe_Hybrid_01_CRC : 0|8@1+ (1,0) [0|255] "" Motor_Hybrid_MQB + SG_ Getriebe_Hybrid_01_BZ : 8|4@1+ (1,0) [0|15] "" Motor_Hybrid_MQB + SG_ GE_HYB_Fehlerstatus : 12|2@1+ (1,0) [0|3] "" Motor_Hybrid_MQB + SG_ GE_HYB_Freigabe_K0 : 16|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB + SG_ GE_HYB_Freigabe_LL_Reg : 17|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB + SG_ GE_HYB_Freig_sSchl_K0 : 18|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB + SG_ GE_HYB_Freig_VM_EM_Stop : 19|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB + SG_ GE_HYB_Wiederstart : 20|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB + SG_ GE_HYB_Filt_MomAufbau : 21|3@1+ (1,0) [0|7] "" Motor_Hybrid_MQB SG_ GE_HYB_nK0 : 24|8@1+ (25,0) [0|6350] "Unit_MinutInver" Vector__XXX - SG_ GE_HYB_MomEingriff_EM : 32|6@1+ (0.5,0) [0|31.5] "Unit_NewtoMeter" LEH_MQB - SG_ GE_HYB_VZ_MomEingriff_EM : 38|1@1+ (1,0) [0|1] "" LEH_MQB - SG_ GE_HYB_Sportfaktor : 56|4@1+ (1,0) [0|15] "" Motor_Hybrid_MQB - SG_ GE_HYB_VM_akt_halten : 61|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB - SG_ GE_HYB_StartAnf : 62|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB - SG_ GE_HYB_VM_Startkontr : 63|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB + SG_ GE_HYB_MomEingriff_EM : 32|6@1+ (0.5,0) [0|31.5] "Unit_NewtoMeter" LEH_MQB + SG_ GE_HYB_VZ_MomEingriff_EM : 38|1@1+ (1,0) [0|1] "" LEH_MQB + SG_ GE_HYB_Sportfaktor : 56|4@1+ (1,0) [0|15] "" Motor_Hybrid_MQB + SG_ GE_HYB_VM_akt_halten : 61|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB + SG_ GE_HYB_StartAnf : 62|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB + SG_ GE_HYB_VM_Startkontr : 63|1@1+ (1,0) [0|1] "" Motor_Hybrid_MQB BO_ 299 GRA_ACC_01: 8 Gateway_MQB - SG_ GRA_ACC_01_CRC : 0|8@1+ (1,0) [0|255] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GRA_ACC_01_BZ : 8|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GRA_Hauptschalter : 12|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GRA_Abbrechen : 13|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GRA_Typ_Hauptschalter : 14|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GRA_Limiter : 15|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GRA_Tip_Setzen : 16|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GRA_Tip_Hoch : 17|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GRA_Tip_Runter : 18|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GRA_Tip_Wiederaufnahme : 19|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GRA_Verstellung_Zeitluecke : 20|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GRA_Codierung : 22|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GRA_Fehler : 24|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GRA_Typ468 : 25|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ GRA_Tip_Stufe_2 : 27|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GRA_ACC_01_CRC : 0|8@1+ (1,0) [0|255] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GRA_ACC_01_BZ : 8|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GRA_Hauptschalter : 12|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GRA_Abbrechen : 13|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GRA_Typ_Hauptschalter : 14|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GRA_Limiter : 15|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GRA_Tip_Setzen : 16|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GRA_Tip_Hoch : 17|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GRA_Tip_Runter : 18|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GRA_Tip_Wiederaufnahme : 19|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GRA_Verstellung_Zeitluecke : 20|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GRA_Codierung : 22|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GRA_Fehler : 24|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GRA_Typ468 : 25|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ GRA_Tip_Stufe_2 : 27|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB BO_ 960 Klemmen_Status_01: 4 Gateway_MQB - SG_ Klemmen_Status_01_CRC : 0|8@1+ (1,0) [0|255] "" Airbag_MQB,BMS_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ Klemmen_Status_01_BZ : 8|4@1+ (1,0) [0|15] "" Airbag_MQB,BMS_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ Klemmen_Status_01_CRC : 0|8@1+ (1,0) [0|255] "" Airbag_MQB,BMS_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ Klemmen_Status_01_BZ : 8|4@1+ (1,0) [0|15] "" Airbag_MQB,BMS_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ ZAS_Kl_S : 16|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ ZAS_Kl_15 : 17|1@1+ (1,0) [0|1] "" Airbag_MQB,BMS_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ ZAS_Kl_15 : 17|1@1+ (1,0) [0|1] "" Airbag_MQB,BMS_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ ZAS_Kl_X : 18|1@1+ (1,0) [0|1] "" Vector__XXX SG_ ZAS_Kl_50 : 19|1@1+ (1,0) [0|1] "" Vector__XXX BO_ 949 Klima_11: 8 Gateway_MQB - SG_ KL_Drehz_Anh : 0|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ KL_Vorwarn_Komp_ein : 1|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KL_Drehz_Anh : 0|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KL_Vorwarn_Komp_ein : 1|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ KL_AC_Schalter : 2|1@1+ (1,0) [0|1] "" Vector__XXX SG_ KL_Komp_Moment_alt : 3|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ KL_Zonen : 4|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KL_Zonen : 4|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ KL_Vorwarn_Zuheizer_ein : 6|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ KL_Zustand : 7|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KL_Zustand : 7|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ KL_Comp_rev_rq : 8|8@1+ (50,0) [0|8600] "Unit_MinutInver" Vector__XXX SG_ KL_Charisma_FahrPr : 16|4@1+ (1,0) [0|15] "" Vector__XXX SG_ KL_Charisma_Status : 20|2@1+ (1,0) [0|3] "" Vector__XXX SG_ KL_Comp_enable : 23|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ KL_Last_Kompr : 24|8@1+ (0.25,0) [0|63.5] "Unit_NewtoMeter" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KL_Last_Kompr : 24|8@1+ (0.25,0) [0|63.5] "Unit_NewtoMeter" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ KL_Spannungs_Anf : 32|2@1+ (1,0) [0|3] "" Vector__XXX - SG_ KL_Thermomanagement : 34|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ KL_StartStopp_Info : 36|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB - SG_ KL_Anf_KL : 40|8@1+ (0.4,0) [0|101.6] "Unit_PerCent" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ KL_el_Zuheizer_Stufe : 48|3@1+ (1,0) [0|7] "" Motor_Diesel_MQB + SG_ KL_Thermomanagement : 34|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KL_StartStopp_Info : 36|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ KL_Anf_KL : 40|8@1+ (0.4,0) [0|101.6] "Unit_PerCent" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KL_el_Zuheizer_Stufe : 48|3@1+ (1,0) [0|7] "" Motor_Diesel_MQB BO_ 1625 Klimakomp_01: 8 Gateway_MQB SG_ EKL_KD_Fehler : 15|1@1+ (1,0) [0|1] "" Vector__XXX @@ -572,80 +572,80 @@ BO_ 1625 Klimakomp_01: 8 Gateway_MQB SG_ EKL_Comp_Inv_stat : 24|2@1+ (1,0) [0|3] "" Vector__XXX SG_ EKL_Comp_photo_temp_stat : 30|2@1+ (1,0) [0|3] "" Vector__XXX SG_ EKL_Comp_photo_temp : 32|8@1+ (1,0) [0|254] "Unit_DegreCelsi" Vector__XXX - SG_ EKL_Comp_current : 40|8@1+ (0.1,0) [0|25.4] "Unit_Amper" Motor_Hybrid_MQB + SG_ EKL_Comp_current : 40|8@1+ (0.1,0) [0|25.4] "Unit_Amper" Motor_Hybrid_MQB SG_ EKL_Comp_rev_stat : 48|8@1+ (50,0) [0|8600] "Unit_MinutInver" Vector__XXX BO_ 2549088277 KN_Airbag_01: 8 Airbag_MQB SG_ Airbag_01_KompSchutz : 0|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ Airbag_01_Nachlauftyp : 4|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ AB_KD_Fehler : 63|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ Airbag_01_Nachlauftyp : 4|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ AB_KD_Fehler : 63|1@1+ (1,0) [0|1] "" Gateway_MQB BO_ 2549088380 KN_EMotor_01: 8 LEH_MQB SG_ EMotor_KompSchutz : 0|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ EMotor_Nachlauftyp : 4|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ EM_HYB_KD_Fehler : 63|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ EMotor_Nachlauftyp : 4|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ EM_HYB_KD_Fehler : 63|1@1+ (1,0) [0|1] "" Gateway_MQB BO_ 2549088375 KN_Getriebe_01: 8 Getriebe_DQ_Hybrid_MQB SG_ Getriebe_KompSchutz : 0|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ Getriebe_Nachlauftyp : 4|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ GE_KD_Fehler : 63|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ Getriebe_Nachlauftyp : 4|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ GE_KD_Fehler : 63|1@1+ (1,0) [0|1] "" Gateway_MQB BO_ 2549088379 KN_Hybrid_01: 8 BMS_MQB SG_ Hybrid_KompSchutz : 0|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ Hybrid_Nachlauftyp : 4|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ BMS_HYB_KD_Fehler : 63|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ Hybrid_Nachlauftyp : 4|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ BMS_HYB_KD_Fehler : 63|1@1+ (1,0) [0|1] "" Gateway_MQB BO_ 2549088374 KN_MO_01: 8 Motor_Diesel_MQB SG_ Motor_KompSchutz : 0|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ Motor_Nachlauftyp : 4|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ MO_KD_Fehler : 63|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ Motor_Nachlauftyp : 4|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ MO_KD_Fehler : 63|1@1+ (1,0) [0|1] "" Gateway_MQB BO_ 2549088284 KN_SAK: 8 SAK_MQB SG_ SAK_KompSchutz : 0|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ SAK_Nachlauftyp : 4|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ SAK_KD_Fehler : 63|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ SAK_Nachlauftyp : 4|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ SAK_KD_Fehler : 63|1@1+ (1,0) [0|1] "" Gateway_MQB BO_ 779 Kombi_01: 8 Gateway_MQB SG_ KBI_ABS_Lampe : 0|1@1+ (1,0) [0|1] "" Vector__XXX SG_ KBI_ESP_Lampe : 1|1@1+ (1,0) [0|1] "" Vector__XXX SG_ KBI_BKL_Lampe : 2|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ KBI_Airbag_Lampe : 3|1@1+ (1,0) [0|1] "" Airbag_MQB - SG_ KBI_SILA_gueltig : 4|1@1+ (1,0) [0|1] "" Airbag_MQB + SG_ KBI_Airbag_Lampe : 3|1@1+ (1,0) [0|1] "" Airbag_MQB + SG_ KBI_SILA_gueltig : 4|1@1+ (1,0) [0|1] "" Airbag_MQB SG_ KBI_Lenkung_Lampe : 5|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ KBI_Vorglueh_System_Lampe : 6|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB + SG_ KBI_Vorglueh_System_Lampe : 6|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB SG_ KBI_NV_in_Anzeige : 7|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ Kombi_01_BZ : 8|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ Kombi_01_BZ : 8|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ KBI_Anzeigestatus_ACC : 12|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ KBI_Anzeigestatus_GRA : 13|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KBI_Anzeigestatus_GRA : 13|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ KBI_Oeldruck_Schalter : 15|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ KBI_Tankwarnung : 16|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ KBI_MFA_v_Einheit_01 : 17|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ KBI_im_Stellgliedtest : 18|1@1+ (1,0) [0|1] "" Airbag_MQB + SG_ KBI_Tankwarnung : 16|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KBI_MFA_v_Einheit_01 : 17|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KBI_im_Stellgliedtest : 18|1@1+ (1,0) [0|1] "" Airbag_MQB SG_ KBI_Anzeigefehler_LDW : 19|2@1+ (1,0) [0|3] "" Vector__XXX SG_ KBI_Variante_USA : 21|1@1+ (1,0) [0|1] "" Vector__XXX SG_ KBI_Oeldruckwarnung : 22|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ KBI_Handbremse : 23|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ KBI_Handbremse : 23|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB SG_ KBI_V_Digital : 24|9@1+ (1,0) [0|511] "" Vector__XXX SG_ KBI_PLA_in_Anzeige : 33|1@1+ (1,0) [0|1] "" Vector__XXX SG_ KBI_Anzeigefehler_NV : 34|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ KBI_Anzeigestatus_LIM : 35|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ KBI_angez_Geschw : 48|10@1+ (0.32,0) [0|325.12] "Unit_KiloMeterPerHour" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ KBI_Einheit_Tacho : 58|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KBI_Anzeigestatus_LIM : 35|2@1+ (1,0) [0|3] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KBI_angez_Geschw : 48|10@1+ (0.32,0) [0|325.12] "Unit_KiloMeterPerHour" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KBI_Einheit_Tacho : 58|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ KBI_Konsistenz_ACC : 59|1@1+ (1,0) [0|1] "" Vector__XXX SG_ KBI_Fehler_Anzeige_ACC : 60|1@1+ (1,0) [0|1] "" Vector__XXX SG_ KBI_Anzeigefehler_SWA : 61|2@1+ (1,0) [0|3] "" Vector__XXX BO_ 1719 Kombi_02: 8 Gateway_MQB SG_ KBI_Kilometerstand : 0|20@1+ (1,0) [0|1048573] "Unit_KiloMeter" Vector__XXX - SG_ KBI_Standzeit_02 : 20|17@1+ (1,0) [0|131068] "Unit_Secon" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ KBI_Inhalt_Tank : 40|7@1+ (1,0) [0|125] "Unit_Liter" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ KBI_FStatus_Tank : 47|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ KBI_QBit_Aussen_Temp_gef : 55|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ KBI_Aussen_Temp_gef : 56|8@1+ (0.5,-50) [-50|75] "Unit_DegreCelsi" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KBI_Standzeit_02 : 20|17@1+ (1,0) [0|131068] "Unit_Secon" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KBI_Inhalt_Tank : 40|7@1+ (1,0) [0|125] "Unit_Liter" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KBI_FStatus_Tank : 47|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KBI_QBit_Aussen_Temp_gef : 55|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ KBI_Aussen_Temp_gef : 56|8@1+ (0.5,-50) [-50|75] "Unit_DegreCelsi" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB BO_ 982 Licht_hinten_01: 8 Gateway_MQB - SG_ Licht_hinten_01_BZ : 0|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ BCM2_Bremsl_durch_ECD : 5|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ Licht_hinten_01_BZ : 0|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ BCM2_Bremsl_durch_ECD : 5|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ LH_Aussenlicht_def : 7|1@1+ (1,0) [0|1] "" Vector__XXX SG_ LH_Standlicht_H_aktiv : 8|1@1+ (1,0) [0|1] "" Vector__XXX SG_ LH_Parklicht_HL_aktiv : 9|1@1+ (1,0) [0|1] "" Vector__XXX @@ -676,253 +676,240 @@ BO_ 982 Licht_hinten_01: 8 Gateway_MQB SG_ LH_SL_BRL_BLK_re_def : 42|1@1+ (1,0) [0|1] "" Vector__XXX SG_ LH_Brems_Blk_re_def : 43|1@1+ (1,0) [0|1] "" Vector__XXX SG_ LH_Kennzl_def : 48|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ LH_3_Bremsl_def : 49|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ LH_3_Bremsl_def : 49|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ LH_Nebel_mi_def : 50|1@1+ (1,0) [0|1] "" Vector__XXX SG_ LH_Rueckf_mi_def : 51|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ LH_Bremsl_li_ges_def : 54|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ LH_Bremsl_re_ges_def : 55|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ LH_Bremsl_li_ges_def : 54|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ LH_Bremsl_re_ges_def : 55|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB BO_ 134 LWI_01: 8 Gateway_MQB - SG_ LWI_01_CRC : 0|8@1+ (1,0) [0|255] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ LWI_01_BZ : 8|4@1+ (1,0) [0|15] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ LWI_Sensorstatus : 12|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ LWI_01_CRC : 0|8@1+ (1,0) [0|255] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ LWI_01_BZ : 8|4@1+ (1,0) [0|15] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ LWI_Sensorstatus : 12|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ LWI_QBit_Sub_Daten : 13|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ LWI_QBit_Lenkradwinkel : 15|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ LWI_Lenkradwinkel : 16|13@1+ (0.1,0) [0|800] "Unit_DegreOfArc" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ LWI_VZ_Lenkradwinkel : 29|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ LWI_VZ_Lenkradw_Geschw : 30|1@1+ (1,0) [0|1] "" Vector__XXX SG_ LWI_Lenkradw_Geschw : 31|9@1+ (5,0) [0|2500] "Unit_DegreOfArcPerSecon" Vector__XXX SG_ LWI_Sub_Daten : 40|16@1+ (1,0) [0|65535] "" Vector__XXX + SG_ LWI_Lenkradwinkel : 16|13@1+ (0.1,0) [0|800] "Unit_DegreOfArc" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ LWI_QBit_Lenkradwinkel : 15|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ LWI_VZ_Lenkradwinkel : 29|1@1+ (1,0) [0|1] "" Airbag_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB BO_ 263 Motor_04: 8 Motor_Diesel_MQB - SG_ MO_Istgang : 8|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ MO_Sollgang : 12|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ MO_Oeldruck : 16|8@1+ (0.04,0) [0|10] "Unit_Bar" Gateway_MQB - SG_ MO_Anzeigedrehz : 24|12@1+ (3,0) [0|12282] "Unit_MinutInver" Gateway_MQB - SG_ MO_Schaltempf_verfbar : 38|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Ladedruck : 39|9@1+ (0.01,0) [0|5.1] "Unit_Bar" Gateway_MQB - SG_ MO_KVS : 48|15@1+ (1,0) [0|32767] "Unit_MicroLiter" Gateway_MQB - SG_ MO_KVS_Ueberlauf : 63|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Istgang : 8|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ MO_Sollgang : 12|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ MO_Oeldruck : 16|8@1+ (0.04,0) [0|10] "Unit_Bar" Gateway_MQB + SG_ MO_Anzeigedrehz : 24|12@1+ (3,0) [0|12282] "Unit_MinutInver" Gateway_MQB + SG_ MO_Schaltempf_verfbar : 38|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Ladedruck : 39|9@1+ (0.01,0) [0|5.1] "Unit_Bar" Gateway_MQB + SG_ MO_KVS : 48|15@1+ (1,0) [0|32767] "Unit_MicroLiter" Gateway_MQB + SG_ MO_KVS_Ueberlauf : 63|1@1+ (1,0) [0|1] "" Gateway_MQB BO_ 1600 Motor_07: 8 Motor_Diesel_MQB - SG_ MO_QBit_Ansaugluft_Temp : 0|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_QBit_Oel_Temp : 1|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_QBit_Kuehlmittel_Temp : 2|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB - SG_ MO_Stellgliedtest_Soundaktuator : 3|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_HYB_Fehler_HV_Netz : 4|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_aktives_Getriebeheizen : 5|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Absperrventil_oeffnen : 6|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ MO_Ansaugluft_Temp : 8|8@1+ (0.75,-48) [-48|141.75] "Unit_DegreCelsi" Gateway_MQB - SG_ MO_Oel_Temp : 16|8@1+ (1,-60) [-60|192] "Unit_DegreCelsi" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Kuehlmittel_Temp : 24|8@1+ (0.75,-48) [-48|141.75] "Unit_DegreCelsi" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB - SG_ MO_Hoeheninfo : 32|8@1+ (0.00781,0) [0|1.98374] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Kennfeldk : 40|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Versionsinfo : 41|6@1+ (1,0) [0|63] "" Gateway_MQB - SG_ MO_Getriebe_kuehlen : 47|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Mom_Traegheit_02 : 48|5@1+ (0.01,0) [0|0.31] "Unit_KiloGramMeterSquar" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Heizungspumpenansteuerung : 53|4@1+ (10,0) [0|100] "Unit_PerCent" Gateway_MQB - SG_ MO_SpannungsAnf : 57|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Nachlaufzeit_Heizungspumpe : 58|6@1+ (15,0) [0|945] "Unit_Secon" Gateway_MQB + SG_ MO_QBit_Ansaugluft_Temp : 0|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_QBit_Oel_Temp : 1|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_QBit_Kuehlmittel_Temp : 2|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB + SG_ MO_Stellgliedtest_Soundaktuator : 3|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_HYB_Fehler_HV_Netz : 4|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_aktives_Getriebeheizen : 5|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Absperrventil_oeffnen : 6|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ MO_Ansaugluft_Temp : 8|8@1+ (0.75,-48) [-48|141.75] "Unit_DegreCelsi" Gateway_MQB + SG_ MO_Oel_Temp : 16|8@1+ (1,-60) [-60|192] "Unit_DegreCelsi" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Kuehlmittel_Temp : 24|8@1+ (0.75,-48) [-48|141.75] "Unit_DegreCelsi" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB + SG_ MO_Hoeheninfo : 32|8@1+ (0.00781,0) [0|1.98374] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Kennfeldk : 40|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Versionsinfo : 41|6@1+ (1,0) [0|63] "" Gateway_MQB + SG_ MO_Getriebe_kuehlen : 47|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Mom_Traegheit_02 : 48|5@1+ (0.01,0) [0|0.31] "Unit_KiloGramMeterSquar" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Heizungspumpenansteuerung : 53|4@1+ (10,0) [0|100] "Unit_PerCent" Gateway_MQB + SG_ MO_SpannungsAnf : 57|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Nachlaufzeit_Heizungspumpe : 58|6@1+ (15,0) [0|945] "Unit_Secon" Gateway_MQB BO_ 1607 Motor_09: 8 Motor_Diesel_MQB - SG_ MO_ITM_Kuehlmittel_Temp : 0|8@1+ (0.75,-48) [-45.75|143.25] "Unit_DegreCelsi" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_E85_Sensor : 8|4@1+ (10,0) [0|100] "Unit_PerCent" Gateway_MQB - SG_ SCR_Anz_Motorstarts : 12|4@1+ (1,0) [0|8] "" Gateway_MQB - SG_ SCR_Reichweite : 16|15@1+ (1,0) [0|32766] "" Gateway_MQB - SG_ SCR_Warnstufe_1 : 32|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ SCR_Warnstufe_2 : 33|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ SCR_Text : 34|3@1+ (1,0) [0|7] "" Gateway_MQB - SG_ SCR_Akustik : 37|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ MO_Kraftstofffilter_Wasser : 40|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ SCR_Systemfehler : 41|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ SCR_Inducement_Strategie : 42|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ MO_CO2_Faktor : 44|12@1+ (1,0) [1|4094] "Unit_GramPerLiter" Gateway_MQB - SG_ MO_MKB_MUX M : 56|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ MO_MKB_01 m0 : 59|5@1+ (1,0) [0|31] "" Gateway_MQB - SG_ MO_MKB_02 m1 : 59|5@1+ (1,0) [0|31] "" Gateway_MQB - SG_ MO_MKB_03 m2 : 59|5@1+ (1,0) [0|31] "" Gateway_MQB - SG_ MO_MKB_04 m3 : 59|5@1+ (1,0) [0|31] "" Gateway_MQB + SG_ MO_ITM_Kuehlmittel_Temp : 0|8@1+ (0.75,-48) [-45.75|143.25] "Unit_DegreCelsi" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_E85_Sensor : 8|4@1+ (10,0) [0|100] "Unit_PerCent" Gateway_MQB + SG_ SCR_Anz_Motorstarts : 12|4@1+ (1,0) [0|8] "" Gateway_MQB + SG_ SCR_Reichweite : 16|15@1+ (1,0) [0|32766] "" Gateway_MQB + SG_ SCR_Warnstufe_1 : 32|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ SCR_Warnstufe_2 : 33|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ SCR_Text : 34|3@1+ (1,0) [0|7] "" Gateway_MQB + SG_ SCR_Akustik : 37|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ MO_Kraftstofffilter_Wasser : 40|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ SCR_Systemfehler : 41|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ SCR_Inducement_Strategie : 42|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ MO_CO2_Faktor : 44|12@1+ (1,0) [1|4094] "Unit_GramPerLiter" Gateway_MQB BO_ 167 Motor_11: 8 Motor_Diesel_MQB - SG_ Motor_11_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ Motor_11_BZ : 8|4@1+ (1,0) [0|15] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Mom_Soll_Roh : 12|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Mom_Ist_Summe : 22|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,SAK_MQB - SG_ MO_Mom_Traegheit_Summe : 32|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Mom_Soll_gefiltert : 42|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Mom_Schub : 52|9@1+ (1,-509) [-509|0] "Unit_NewtoMeter" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Status_Normalbetrieb_01 : 61|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_erste_Ungenauschwelle : 62|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_QBit_Motormomente : 63|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ Motor_11_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ Motor_11_BZ : 8|4@1+ (1,0) [0|15] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Mom_Soll_Roh : 12|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Mom_Ist_Summe : 22|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,SAK_MQB + SG_ MO_Mom_Traegheit_Summe : 32|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Mom_Soll_gefiltert : 42|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Mom_Schub : 52|9@1+ (1,-509) [-509|0] "Unit_NewtoMeter" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Status_Normalbetrieb_01 : 61|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_erste_Ungenauschwelle : 62|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_QBit_Motormomente : 63|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB BO_ 168 Motor_12: 8 Motor_Diesel_MQB - SG_ Motor_12_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB - SG_ Motor_12_BZ : 8|4@1+ (1,0) [0|15] "" BMS_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB - SG_ MO_Mom_neg_verfuegbar : 12|9@1+ (1,-509) [-509|0] "Unit_NewtoMeter" Gateway_MQB - SG_ MO_Mom_Begr_stat : 21|9@1+ (1,0) [0|509] "Unit_NewtoMeter" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Mom_Begr_dyn : 30|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Gateway_MQB - SG_ MO_Momentenintegral_02 : 40|7@1+ (1,0) [0|100] "Unit_PerCent" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_QBit_Drehzahl_01 : 47|1@1+ (1,0) [0|1] "" BMS_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB - SG_ MO_Drehzahl_01 : 48|16@1+ (0.25,0) [0|16383] "Unit_MinutInver" BMS_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,SAK_MQB + SG_ Motor_12_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB + SG_ Motor_12_BZ : 8|4@1+ (1,0) [0|15] "" BMS_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB + SG_ MO_Mom_neg_verfuegbar : 12|9@1+ (1,-509) [-509|0] "Unit_NewtoMeter" Gateway_MQB + SG_ MO_Mom_Begr_stat : 21|9@1+ (1,0) [0|509] "Unit_NewtoMeter" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Mom_Begr_dyn : 30|10@1+ (1,-509) [-509|509] "Unit_NewtoMeter" Gateway_MQB + SG_ MO_Momentenintegral_02 : 40|7@1+ (1,0) [0|100] "Unit_PerCent" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_QBit_Drehzahl_01 : 47|1@1+ (1,0) [0|1] "" BMS_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB + SG_ MO_Drehzahl_01 : 48|16@1+ (0.25,0) [0|16383] "Unit_MinutInver" BMS_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,SAK_MQB BO_ 958 Motor_14: 8 Motor_Diesel_MQB - SG_ MO_StartStopp_Status : 12|2@1+ (1,0) [0|3] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_StartStopp_Wiederstart : 14|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_StartStopp_Motorstopp : 15|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Freig_Reku : 16|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ MO_Kl_75 : 18|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Kl_50 : 19|1@1+ (1,0) [0|1] "" Gateway_MQB,LEH_MQB - SG_ MO_Gangposition : 20|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ MO_StartStopp_Fahrerwunsch : 24|2@1+ (1,0) [0|3] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_HYB_Fahrbereitschaft : 26|1@1+ (1,0) [0|1] "" BMS_MQB,Gateway_MQB - SG_ MO_Ext_E_Fahrt_aktiv : 27|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Fahrer_bremst : 28|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_QBit_Fahrer_bremst : 29|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_BLS : 30|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Konsistenz_Bremsped : 31|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Timeout_ESP : 32|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Klima_Eingr : 33|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ MO_Aussp_Anlass : 35|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Freig_Anlass : 36|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Kuppl_schalter : 37|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Interlock : 38|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Motor_laeuft : 39|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Kickdown : 40|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Status_Zylabschalt_01 : 41|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_EKlKomLeiRed : 42|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ MO_Handshake_STH : 44|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_BKV_Unterdruckwarnung : 45|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Freigabe_Segeln : 46|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_PTC_Status : 47|3@1+ (1,0) [0|7] "" Gateway_MQB - SG_ MO_QBit_Gangposition : 50|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Signalquelle_Gangposition : 51|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Remotestart_Betrieb : 52|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_StartStopp_Status : 12|2@1+ (1,0) [0|3] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_StartStopp_Wiederstart : 14|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_StartStopp_Motorstopp : 15|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Freig_Reku : 16|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ MO_Kl_75 : 18|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Kl_50 : 19|1@1+ (1,0) [0|1] "" Gateway_MQB,LEH_MQB + SG_ MO_Gangposition : 20|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ MO_StartStopp_Fahrerwunsch : 24|2@1+ (1,0) [0|3] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_HYB_Fahrbereitschaft : 26|1@1+ (1,0) [0|1] "" BMS_MQB,Gateway_MQB + SG_ MO_Ext_E_Fahrt_aktiv : 27|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Fahrer_bremst : 28|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_QBit_Fahrer_bremst : 29|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_BLS : 30|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Konsistenz_Bremsped : 31|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Timeout_ESP : 32|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Klima_Eingr : 33|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ MO_Aussp_Anlass : 35|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Freig_Anlass : 36|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Kuppl_schalter : 37|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Interlock : 38|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Motor_laeuft : 39|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Kickdown : 40|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Status_Zylabschalt_01 : 41|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_EKlKomLeiRed : 42|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ MO_Handshake_STH : 44|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_BKV_Unterdruckwarnung : 45|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Freigabe_Segeln : 46|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_PTC_Status : 47|3@1+ (1,0) [0|7] "" Gateway_MQB + SG_ MO_QBit_Gangposition : 50|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Signalquelle_Gangposition : 51|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Remotestart_Betrieb : 52|1@1+ (1,0) [0|1] "" Gateway_MQB BO_ 1631 Motor_16: 8 Motor_Diesel_MQB - SG_ TSK_QBit_Steigung : 12|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ TSK_QBit_Fahrzeugmasse : 13|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_SpannungsAnf_02 : 14|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ MO_DPF_reg : 16|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Heizstrom_EKAT : 17|7@1+ (1,0) [0|126] "Unit_Amper" Gateway_MQB - SG_ MO_Heizstrom_SCR : 24|6@1+ (1,0) [0|62] "Unit_Amper" Gateway_MQB - SG_ TSK_Fahrzeugmasse_02 : 48|8@1+ (32,0) [0|8128] "Unit_KiloGram" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ TSK_Steigung : 56|8@1+ (0.8,-101.6) [-101.6|101.6] "Unit_PerCent" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ TSK_QBit_Steigung : 12|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ TSK_QBit_Fahrzeugmasse : 13|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_SpannungsAnf_02 : 14|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ MO_DPF_reg : 16|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Heizstrom_EKAT : 17|7@1+ (1,0) [0|126] "Unit_Amper" Gateway_MQB + SG_ MO_Heizstrom_SCR : 24|6@1+ (1,0) [0|62] "Unit_Amper" Gateway_MQB + SG_ TSK_Fahrzeugmasse_02 : 48|8@1+ (32,0) [0|8128] "Unit_KiloGram" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ TSK_Steigung : 56|8@1+ (0.8,-101.6) [-101.6|101.6] "Unit_PerCent" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB BO_ 812 Motor_17: 8 Motor_Diesel_MQB - SG_ MO_Prio_MAX_Wunschdrehzahl : 12|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Prio_MIN_Wunschdrehzahl : 13|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Prio_MAX_Wunschdrehzahl : 12|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Prio_MIN_Wunschdrehzahl : 13|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB SG_ MO_Luftpfad_aktiv : 14|1@1+ (1,0) [0|1] "" Vector__XXX SG_ MO_v_Begrenz_Aktivierbar : 15|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ MO_Drehzahlbeeinflussung : 16|8@1+ (0.39,0) [0|99.45] "Unit_PerCent" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_MIN_Wunschdrehzahl : 24|8@1+ (25,0) [0|6350] "Unit_MinutInver" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_MAX_Wunschdrehzahl : 32|9@1+ (25,0) [0|12750] "Unit_MinutInver" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Charisma_FahrPr : 41|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ MO_Charisma_Status : 45|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ MO_Drehzahlbeeinflussung : 16|8@1+ (0.39,0) [0|99.45] "Unit_PerCent" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_MIN_Wunschdrehzahl : 24|8@1+ (25,0) [0|6350] "Unit_MinutInver" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_MAX_Wunschdrehzahl : 32|9@1+ (25,0) [0|12750] "Unit_MinutInver" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Charisma_FahrPr : 41|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ MO_Charisma_Status : 45|2@1+ (1,0) [0|3] "" Gateway_MQB BO_ 1648 Motor_18: 8 Motor_Diesel_MQB - SG_ MO_Hybrid_StartStopp_LED : 43|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ MO_Eis_Offroad_LED : 45|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ MO_Anzahl_Abgesch_Zyl : 47|3@1+ (1,0) [0|7] "" Gateway_MQB - SG_ MO_Zylabsch_Texte : 50|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ MO_E85_BS_Texte : 52|3@1+ (1,0) [0|7] "" Gateway_MQB - SG_ MO_Drehzahl_Warnung : 55|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_obere_Drehzahlgrenze : 56|8@1+ (50,0) [50|12750] "Unit_MinutInver" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Hybrid_StartStopp_LED : 43|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ MO_Eis_Offroad_LED : 45|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ MO_Anzahl_Abgesch_Zyl : 47|3@1+ (1,0) [0|7] "" Gateway_MQB + SG_ MO_Zylabsch_Texte : 50|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ MO_E85_BS_Texte : 52|3@1+ (1,0) [0|7] "" Gateway_MQB + SG_ MO_Drehzahl_Warnung : 55|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_obere_Drehzahlgrenze : 56|8@1+ (50,0) [50|12750] "Unit_MinutInver" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB BO_ 289 Motor_20: 8 Motor_Diesel_MQB - SG_ MO_Fahrpedalrohwert_01 : 12|8@1+ (0.4,0) [0|101.6] "Unit_PerCent" Airbag_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_QBit_Fahrpedalwerte_01 : 20|1@1+ (1,0) [0|1] "" Airbag_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Fahrpedalgradient : 21|8@1+ (25,0) [0|6350] "Unit_PerCentPerSecon" Airbag_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Sig_Fahrpedalgradient : 29|1@1+ (1,0) [0|1] "" Airbag_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_rel_Saugrohrdruck : 30|6@1+ (18,0) [0|1116] "Unit_MilliBar" Gateway_MQB - SG_ MO_rel_Saugrohrdruck_gem_err : 36|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Moment_im_Leerlauf : 37|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Schubabschaltung : 38|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Solldrehz_Leerlauf : 40|8@1+ (10,0) [0|2540] "Unit_MinutInver" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Fahrpedalrohwert_01 : 12|8@1+ (0.4,0) [0|101.6] "Unit_PerCent" Airbag_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_QBit_Fahrpedalwerte_01 : 20|1@1+ (1,0) [0|1] "" Airbag_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Fahrpedalgradient : 21|8@1+ (25,0) [0|6350] "Unit_PerCentPerSecon" Airbag_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Sig_Fahrpedalgradient : 29|1@1+ (1,0) [0|1] "" Airbag_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_rel_Saugrohrdruck : 30|6@1+ (18,0) [0|1116] "Unit_MilliBar" Gateway_MQB + SG_ MO_rel_Saugrohrdruck_gem_err : 36|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Moment_im_Leerlauf : 37|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Schubabschaltung : 38|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Solldrehz_Leerlauf : 40|8@1+ (10,0) [0|2540] "Unit_MinutInver" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB BO_ 967 Motor_26: 8 Motor_Diesel_MQB - SG_ MO_Kuehlerluefter_MUX M : 0|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Kuehlerluefter_1 m0 : 1|7@1+ (1,0) [0|100] "Unit_PerCent" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Kuehlerluefter_2 m1 : 1|7@1+ (1,0) [0|100] "Unit_PerCent" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_HYB_Status_HV_Ladung : 8|3@1+ (1,0) [0|7] "" Gateway_MQB - SG_ WIV_Anzeige_aktiv : 12|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ WIV_Oelmin_Warn : 13|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ WIV_Sensorfehler : 14|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ WIV_Schieflage : 15|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ WIV_Oelstand : 16|4@1+ (12.5,0) [0|100] "Unit_PerCent" Gateway_MQB - SG_ MO_Zustand_HWP : 20|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ WIV_Oelsystem_aktiv : 24|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ WIV_nicht_betriebswarm : 25|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ WIV_Ueberfuell_Warn : 26|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ WIV_laufender_Motor : 27|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_HYB_Text_1 : 28|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_HYB_Text_2 : 29|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_HYB_Text_3 : 30|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_HYB_Text_4 : 31|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Text_Motorstart : 32|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ MO_HYB_Text_5 : 36|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_HYB_Text_6 : 37|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_HYB_Text_7 : 38|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Text_Partikelfil_Reg : 41|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ WIV_Oelmenge : 43|5@1+ (125,0) [0|3875] "Unit_MilliLiter" Gateway_MQB - SG_ MO_Systemlampe : 48|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_OBD2_Lampe : 49|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Heissleuchte : 50|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Partikel_Lampe : 51|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Winterfahrprog : 52|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ WIV_Oelstand_nicht_vorhanden : 53|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ WIV_nachfuellanzeige_ein : 54|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ WIV_Ueberfuell_deaktiv : 55|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ WIV_Unterfuell_Warn : 56|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Tankdeckel_Lampe : 57|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Text_Tankdeckelwarn : 58|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ WIV_Oeldr_Warn_Motor : 60|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_HYB_Status_HV_Ladung : 8|3@1+ (1,0) [0|7] "" Gateway_MQB + SG_ WIV_Anzeige_aktiv : 12|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ WIV_Oelmin_Warn : 13|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ WIV_Sensorfehler : 14|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ WIV_Schieflage : 15|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ WIV_Oelstand : 16|4@1+ (12.5,0) [0|100] "Unit_PerCent" Gateway_MQB + SG_ MO_Zustand_HWP : 20|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ WIV_Oelsystem_aktiv : 24|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ WIV_nicht_betriebswarm : 25|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ WIV_Ueberfuell_Warn : 26|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ WIV_laufender_Motor : 27|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_HYB_Text_1 : 28|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_HYB_Text_2 : 29|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_HYB_Text_3 : 30|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_HYB_Text_4 : 31|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Text_Motorstart : 32|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ MO_HYB_Text_5 : 36|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_HYB_Text_6 : 37|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_HYB_Text_7 : 38|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Text_Partikelfil_Reg : 41|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ WIV_Oelmenge : 43|5@1+ (125,0) [0|3875] "Unit_MilliLiter" Gateway_MQB + SG_ MO_Systemlampe : 48|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_OBD2_Lampe : 49|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Heissleuchte : 50|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Partikel_Lampe : 51|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Winterfahrprog : 52|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ WIV_Oelstand_nicht_vorhanden : 53|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ WIV_nachfuellanzeige_ein : 54|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ WIV_Ueberfuell_deaktiv : 55|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ WIV_Unterfuell_Warn : 56|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Tankdeckel_Lampe : 57|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Text_Tankdeckelwarn : 58|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ WIV_Oeldr_Warn_Motor : 60|1@1+ (1,0) [0|1] "" Gateway_MQB BO_ 1601 Motor_Code_01: 8 Motor_Diesel_MQB - SG_ Motor_Code_01_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB - SG_ Motor_Code_01_BZ : 8|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ MO_Faktor_Momente_02 : 12|2@1+ (1,0) [0|3] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Hybridfahrzeug : 14|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ MO_Code : 16|8@1+ (1,0) [0|255] "" Gateway_MQB,SAK_MQB - SG_ MO_Getriebe_Code : 24|6@1+ (1,0) [0|63] "" Gateway_MQB - SG_ MO_StartStopp_Codiert : 30|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Anzahl_Zyl : 32|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ MO_Kraftstoffart : 36|4@1+ (1,0) [0|15] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Hubraum : 40|7@1+ (0.1,0) [0|12.7] "Unit_Liter" Gateway_MQB - SG_ MO_Ansaugsystem : 47|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ MO_Leistung : 48|9@1+ (1,0) [0|511] "Unit_KiloWatt" Gateway_MQB - SG_ MO_Abgastyp_EOBD : 57|1@1+ (1,0) [0|1] "" BMS_MQB,Gateway_MQB,LEH_MQB - SG_ MO_Abgastyp_OBD : 58|1@1+ (1,0) [0|1] "" BMS_MQB,Gateway_MQB,LEH_MQB - SG_ MO_DPF_verbaut : 59|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ TSK_Codierung : 60|3@1+ (1,0) [0|7] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ MO_Einspritzart : 63|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ Motor_Code_01_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB + SG_ Motor_Code_01_BZ : 8|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ MO_Faktor_Momente_02 : 12|2@1+ (1,0) [0|3] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Hybridfahrzeug : 14|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ MO_Code : 16|8@1+ (1,0) [0|255] "" Gateway_MQB,SAK_MQB + SG_ MO_Getriebe_Code : 24|6@1+ (1,0) [0|63] "" Gateway_MQB + SG_ MO_StartStopp_Codiert : 30|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Anzahl_Zyl : 32|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ MO_Kraftstoffart : 36|4@1+ (1,0) [0|15] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Hubraum : 40|7@1+ (0.1,0) [0|12.7] "Unit_Liter" Gateway_MQB + SG_ MO_Ansaugsystem : 47|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ MO_Leistung : 48|9@1+ (1,0) [0|511] "Unit_KiloWatt" Gateway_MQB + SG_ MO_Abgastyp_EOBD : 57|1@1+ (1,0) [0|1] "" BMS_MQB,Gateway_MQB,LEH_MQB + SG_ MO_Abgastyp_OBD : 58|1@1+ (1,0) [0|1] "" BMS_MQB,Gateway_MQB,LEH_MQB + SG_ MO_DPF_verbaut : 59|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ TSK_Codierung : 60|3@1+ (1,0) [0|7] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ MO_Einspritzart : 63|1@1+ (1,0) [0|1] "" Gateway_MQB BO_ 157 Motor_Hybrid_01: 8 Motor_Hybrid_MQB - SG_ Motor_Hybrid_01_CRC : 0|8@1+ (1,0) [0|255] "" Getriebe_DQ_Hybrid_MQB - SG_ Motor_Hybrid_01_BZ : 8|4@1+ (1,0) [0|15] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB - SG_ MO_HYB_IstStatusK0 : 12|2@1+ (1,0) [0|3] "" Getriebe_DQ_Hybrid_MQB - SG_ MO_HYB_max_ind_VM_Mom : 16|10@1+ (1,0) [0|1021] "Unit_NewtoMeter" Getriebe_DQ_Hybrid_MQB - SG_ MO_HYB_Zielzustand : 26|3@1+ (1,0) [0|7] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB + SG_ Motor_Hybrid_01_CRC : 0|8@1+ (1,0) [0|255] "" Getriebe_DQ_Hybrid_MQB + SG_ Motor_Hybrid_01_BZ : 8|4@1+ (1,0) [0|15] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB + SG_ MO_HYB_IstStatusK0 : 12|2@1+ (1,0) [0|3] "" Getriebe_DQ_Hybrid_MQB + SG_ MO_HYB_max_ind_VM_Mom : 16|10@1+ (1,0) [0|1021] "Unit_NewtoMeter" Getriebe_DQ_Hybrid_MQB + SG_ MO_HYB_Zielzustand : 26|3@1+ (1,0) [0|7] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB SG_ MO_HYB_Startmodus : 29|3@1+ (1,0) [0|7] "" Vector__XXX - SG_ MO_HYB_Startmodus_PQ3x : 32|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB - SG_ MO_HYB_Stoppmodus : 33|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB - SG_ MO_HYB_VM_Mom_oE : 40|10@1+ (1,-100) [-100|922] "Unit_NewtoMeter" Getriebe_DQ_Hybrid_MQB - SG_ MO_HYB_VM_aktiv : 50|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB - SG_ MO_HYB_Schaltverhinderung : 51|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB - SG_ MO_HYB_Selektor_Momverlauf_EM M : 53|3@1+ (1,0) [0|7] "" Getriebe_DQ_Hybrid_MQB - SG_ MO_HYB_Momverlauf_Rek m1 : 56|8@1+ (2,0) [0|510] "Unit_NewtoMeter" Getriebe_DQ_Hybrid_MQB - SG_ MO_HYB_KnickDZ_Rek m2 : 56|8@1+ (12.5,0) [0|3150] "Unit_MinutInver" Getriebe_DQ_Hybrid_MQB - SG_ MO_HYB_Momverlauf_EM m3 : 56|8@1+ (2,0) [0|510] "Unit_NewtoMeter" Getriebe_DQ_Hybrid_MQB - SG_ MO_HYB_KnickDZ_EM m4 : 56|8@1+ (12.5,0) [0|3150] "Unit_MinutInver" Getriebe_DQ_Hybrid_MQB + SG_ MO_HYB_Startmodus_PQ3x : 32|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB + SG_ MO_HYB_Stoppmodus : 33|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB + SG_ MO_HYB_VM_Mom_oE : 40|10@1+ (1,-100) [-100|922] "Unit_NewtoMeter" Getriebe_DQ_Hybrid_MQB + SG_ MO_HYB_VM_aktiv : 50|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB + SG_ MO_HYB_Schaltverhinderung : 51|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB BO_ 811 Motor_Hybrid_02: 8 Motor_Hybrid_MQB - SG_ MO_HYB_E_Faktor : 12|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB - SG_ MO_HYB_Drehzahl_VM : 16|16@1+ (0.25,0) [0|16256] "Unit_MinutInver" Getriebe_DQ_Hybrid_MQB - SG_ MO_HYB_LowSpeedModus : 32|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB + SG_ MO_HYB_E_Faktor : 12|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB + SG_ MO_HYB_Drehzahl_VM : 16|16@1+ (0.25,0) [0|16256] "Unit_MinutInver" Getriebe_DQ_Hybrid_MQB + SG_ MO_HYB_LowSpeedModus : 32|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB BO_ 2600468501 NMH_Airbag_01: 8 Airbag_MQB SG_ NM_Airbag_01_SNI : 0|8@1+ (1,0) [0|255] "" Vector__XXX - SG_ NM_Airbag_01_NM_State : 16|6@1+ (1,0) [0|63] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ NM_Airbag_01_Car_Wakeup : 22|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ NM_Airbag_01_NM_State : 16|6@1+ (1,0) [0|63] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ NM_Airbag_01_Car_Wakeup : 22|1@1+ (1,0) [0|1] "" Gateway_MQB SG_ NM_Airbag_01_Wakeup : 24|8@1+ (1,0) [0|255] "" Vector__XXX SG_ NM_Airbag_01_NM_aktiv_KL15 : 32|1@1+ (1,0) [0|1] "" Vector__XXX SG_ NM_Airbag_01_NM_aktiv_Diagnose : 33|1@1+ (1,0) [0|1] "" Vector__XXX @@ -931,8 +918,8 @@ BO_ 2600468501 NMH_Airbag_01: 8 Airbag_MQB BO_ 2600468604 NMH_EMotor_01: 8 LEH_MQB SG_ NM_EMotor_01_SNI : 0|8@1+ (1,0) [0|255] "" Vector__XXX - SG_ NM_EMotor_01_NM_State : 16|6@1+ (1,0) [0|63] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ NM_EMotor_01_Car_Wakeup : 22|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ NM_EMotor_01_NM_State : 16|6@1+ (1,0) [0|63] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ NM_EMotor_01_Car_Wakeup : 22|1@1+ (1,0) [0|1] "" Gateway_MQB SG_ NM_EMotor_01_Wakeup : 24|8@1+ (1,0) [0|255] "" Vector__XXX SG_ NM_EMotor_01_NM_aktiv_KL15 : 32|1@1+ (1,0) [0|1] "" Vector__XXX SG_ NM_EMotor_01_NM_aktiv_Diagnose : 33|1@1+ (1,0) [0|1] "" Vector__XXX @@ -942,7 +929,7 @@ BO_ 2600468604 NMH_EMotor_01: 8 LEH_MQB BO_ 2600468496 NMH_Gateway: 8 Gateway_MQB SG_ NM_Gateway_SNI : 0|8@1+ (1,0) [0|255] "" Vector__XXX - SG_ NM_Gateway_NM_State : 16|6@1+ (1,0) [0|63] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ NM_Gateway_NM_State : 16|6@1+ (1,0) [0|63] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ NM_Gateway_Car_Wakeup : 22|1@1+ (1,0) [0|1] "" Vector__XXX SG_ NM_Gateway_Wakeup : 24|8@1+ (1,0) [0|255] "" Vector__XXX SG_ NM_Gateway_NM_aktiv_KL15 : 32|1@1+ (1,0) [0|1] "" Vector__XXX @@ -965,8 +952,8 @@ BO_ 2600468496 NMH_Gateway: 8 Gateway_MQB BO_ 2600468599 NMH_Getriebe_01: 8 Getriebe_DQ_Hybrid_MQB SG_ NM_Getriebe_01_SNI : 0|8@1+ (1,0) [0|255] "" Vector__XXX - SG_ NM_Getriebe_01_NM_State : 16|6@1+ (1,0) [0|63] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ NM_Getriebe_01_Car_Wakeup : 22|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ NM_Getriebe_01_NM_State : 16|6@1+ (1,0) [0|63] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ NM_Getriebe_01_Car_Wakeup : 22|1@1+ (1,0) [0|1] "" Gateway_MQB SG_ NM_Getriebe_01_Wakeup : 24|8@1+ (1,0) [0|255] "" Vector__XXX SG_ NM_Getriebe_01_NM_aktiv_KL15 : 32|1@1+ (1,0) [0|1] "" Vector__XXX SG_ NM_Getriebe_01_NM_aktiv_Diagnose : 33|1@1+ (1,0) [0|1] "" Vector__XXX @@ -979,8 +966,8 @@ BO_ 2600468599 NMH_Getriebe_01: 8 Getriebe_DQ_Hybrid_MQB BO_ 2600468603 NMH_Hybrid_01: 8 BMS_MQB SG_ NM_Hybrid_01_SNI : 0|8@1+ (1,0) [0|255] "" Vector__XXX - SG_ NM_Hybrid_01_NM_State : 16|6@1+ (1,0) [0|63] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ NM_Hybrid_01_Car_Wakeup : 22|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ NM_Hybrid_01_NM_State : 16|6@1+ (1,0) [0|63] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ NM_Hybrid_01_Car_Wakeup : 22|1@1+ (1,0) [0|1] "" Gateway_MQB SG_ NM_Hybrid_01_Wakeup : 24|8@1+ (1,0) [0|255] "" Vector__XXX SG_ NM_Hybrid_01_NM_aktiv_KL15 : 32|1@1+ (1,0) [0|1] "" Vector__XXX SG_ NM_Hybrid_01_NM_aktiv_Diagnose : 33|1@1+ (1,0) [0|1] "" Vector__XXX @@ -991,8 +978,8 @@ BO_ 2600468603 NMH_Hybrid_01: 8 BMS_MQB BO_ 2600468598 NMH_MO_01: 8 Motor_Diesel_MQB SG_ NM_MO_01_SNI : 0|8@1+ (1,0) [0|255] "" Vector__XXX - SG_ NM_MO_01_NM_State : 16|6@1+ (1,0) [0|63] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ NM_MO_01_Car_Wakeup : 22|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ NM_MO_01_NM_State : 16|6@1+ (1,0) [0|63] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB,Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ NM_MO_01_Car_Wakeup : 22|1@1+ (1,0) [0|1] "" Gateway_MQB SG_ NM_MO_01_Wakeup : 24|8@1+ (1,0) [0|255] "" Vector__XXX SG_ NM_MO_01_NM_aktiv_KL15 : 32|1@1+ (1,0) [0|1] "" Vector__XXX SG_ NM_MO_01_NM_aktiv_Diagnose : 33|1@1+ (1,0) [0|1] "" Vector__XXX @@ -1008,57 +995,57 @@ BO_ 2600468598 NMH_MO_01: 8 Motor_Diesel_MQB SG_ NM_MO_01_UDS_CC : 63|1@1+ (1,0) [0|1] "" Vector__XXX BO_ 913 OBD_01: 8 Motor_Diesel_MQB - SG_ OBD_Calc_Load_Val : 0|8@1+ (0.39215686275,0) [0|100] "Unit_PerCent" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB - SG_ OBD_Eng_Cool_Temp : 8|8@1+ (1,-40) [-40|215] "Unit_DegreCelsi" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB - SG_ OBD_Abs_Throttle_Pos : 16|8@1+ (0.39215686275,0) [0|100] "Unit_PerCent" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB - SG_ OBD_Abs_Load_Val : 24|16@1+ (0.39215686275,0) [0|25700] "Unit_PerCent" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB - SG_ OBD_Abs_Pedal_Pos : 40|8@1+ (0.39215686275,0) [0|100] "Unit_PerCent" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB - SG_ OBD_Kaltstart_Denominator : 59|1@1+ (1,0) [0|1] "" BMS_MQB,LEH_MQB - SG_ OBD_Minimum_Trip : 60|1@1+ (1,0) [0|1] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB - SG_ OBD_Driving_Cycle : 61|1@1+ (1,0) [0|1] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB - SG_ OBD_Warm_Up_Cycle : 62|1@1+ (1,0) [0|1] "" BMS_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB - SG_ OBD_Normed_Trip : 63|1@1+ (1,0) [0|1] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB + SG_ OBD_Calc_Load_Val : 0|8@1+ (0.39215686275,0) [0|100] "Unit_PerCent" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB + SG_ OBD_Eng_Cool_Temp : 8|8@1+ (1,-40) [-40|215] "Unit_DegreCelsi" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB + SG_ OBD_Abs_Throttle_Pos : 16|8@1+ (0.39215686275,0) [0|100] "Unit_PerCent" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB + SG_ OBD_Abs_Load_Val : 24|16@1+ (0.39215686275,0) [0|25700] "Unit_PerCent" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB + SG_ OBD_Abs_Pedal_Pos : 40|8@1+ (0.39215686275,0) [0|100] "Unit_PerCent" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB + SG_ OBD_Kaltstart_Denominator : 59|1@1+ (1,0) [0|1] "" BMS_MQB,LEH_MQB + SG_ OBD_Minimum_Trip : 60|1@1+ (1,0) [0|1] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB + SG_ OBD_Driving_Cycle : 61|1@1+ (1,0) [0|1] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB + SG_ OBD_Warm_Up_Cycle : 62|1@1+ (1,0) [0|1] "" BMS_MQB,Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB + SG_ OBD_Normed_Trip : 63|1@1+ (1,0) [0|1] "" BMS_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB,LEH_MQB BO_ 1630 OBD_Tankgeber_01: 8 Gateway_MQB - SG_ OBD_TG_F_Status_1 : 0|4@1+ (1,0) [0|15] "" Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ OBD_TG_F_Status_2 : 4|4@1+ (1,0) [0|15] "" Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ OBD_TG_F_Status_3 : 8|4@1+ (1,0) [0|15] "" Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ OBD_TG_F_Status_4 : 12|4@1+ (1,0) [0|15] "" Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ OBD_TG_Sens_Rohwert_1 : 16|12@1+ (0.5,0) [0|2047.5] "Unit_Ohm" Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ OBD_TG_Sens_Rohwert_2 : 28|12@1+ (0.5,0) [0|2047.5] "Unit_Ohm" Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ OBD_TG_Sens_Rohwert_3 : 40|12@1+ (0.5,0) [0|2047.5] "Unit_Ohm" Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ OBD_TG_Sens_Rohwert_4 : 52|12@1+ (0.5,0) [0|2047.5] "Unit_Ohm" Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ OBD_TG_F_Status_1 : 0|4@1+ (1,0) [0|15] "" Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ OBD_TG_F_Status_2 : 4|4@1+ (1,0) [0|15] "" Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ OBD_TG_F_Status_3 : 8|4@1+ (1,0) [0|15] "" Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ OBD_TG_F_Status_4 : 12|4@1+ (1,0) [0|15] "" Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ OBD_TG_Sens_Rohwert_1 : 16|12@1+ (0.5,0) [0|2047.5] "Unit_Ohm" Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ OBD_TG_Sens_Rohwert_2 : 28|12@1+ (0.5,0) [0|2047.5] "Unit_Ohm" Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ OBD_TG_Sens_Rohwert_3 : 40|12@1+ (0.5,0) [0|2047.5] "Unit_Ohm" Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ OBD_TG_Sens_Rohwert_4 : 52|12@1+ (0.5,0) [0|2047.5] "Unit_Ohm" Motor_Hybrid_MQB,Motor_Otto_MQB BO_ 1437 Remotestart_FFB: 8 Gateway_MQB - SG_ RSF_Tastencode_1 : 0|8@1+ (1,0) [0|255] "" Motor_Diesel_MQB,Motor_Otto_MQB - SG_ RSF_Tastencode_2 : 8|8@1+ (1,0) [0|255] "" Motor_Diesel_MQB,Motor_Otto_MQB - SG_ RSF_Tastencode_Maske : 16|8@1+ (1,0) [0|255] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ RSF_Tastencode_1 : 0|8@1+ (1,0) [0|255] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ RSF_Tastencode_2 : 8|8@1+ (1,0) [0|255] "" Motor_Diesel_MQB,Motor_Otto_MQB + SG_ RSF_Tastencode_Maske : 16|8@1+ (1,0) [0|255] "" Motor_Diesel_MQB,Motor_Otto_MQB BO_ 984 RGS_VL_01: 8 Airbag_MQB - SG_ RGS_VL_Texte : 12|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ RGS_VL_Charisma_FahrPr : 14|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ RGS_VL_Charisma_Status : 18|2@1+ (1,0) [0|3] "" Gateway_MQB - SG_ RGS_VL_aktiv : 21|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ RGS_VL_PC_Aktuator_Sitz : 25|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ RGS_VL_PC_Aktuator_Schiebedach : 26|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ RGS_VL_PC_Aktuator_Fenster : 27|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ RGS_VL_PC_Aktuator_Warnblinken : 28|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ RGS_VL_Precrash_Basis : 32|8@1+ (1,0) [0|255] "" Gateway_MQB - SG_ RGS_VL_Precrash_Front : 40|8@1+ (1,0) [0|255] "" Gateway_MQB - SG_ RGS_VL_Precrash_Rear : 48|8@1+ (1,0) [0|255] "" Gateway_MQB + SG_ RGS_VL_Texte : 12|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ RGS_VL_Charisma_FahrPr : 14|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ RGS_VL_Charisma_Status : 18|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ RGS_VL_aktiv : 21|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ RGS_VL_PC_Aktuator_Sitz : 25|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ RGS_VL_PC_Aktuator_Schiebedach : 26|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ RGS_VL_PC_Aktuator_Fenster : 27|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ RGS_VL_PC_Aktuator_Warnblinken : 28|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ RGS_VL_Precrash_Basis : 32|8@1+ (1,0) [0|255] "" Gateway_MQB + SG_ RGS_VL_Precrash_Front : 40|8@1+ (1,0) [0|255] "" Gateway_MQB + SG_ RGS_VL_Precrash_Rear : 48|8@1+ (1,0) [0|255] "" Gateway_MQB BO_ 1528 SAK_01: 8 SAK_MQB - SG_ SAK_Charisma_FahrPr : 16|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ SAK_Charisma_Status : 20|2@1+ (1,0) [0|3] "" Gateway_MQB + SG_ SAK_Charisma_FahrPr : 16|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ SAK_Charisma_Status : 20|2@1+ (1,0) [0|3] "" Gateway_MQB BO_ 1313 STH_01: 8 Gateway_MQB SG_ STH_Funk_ein : 0|1@1+ (1,0) [0|1] "" Vector__XXX SG_ STH_Funk_aus : 1|1@1+ (1,0) [0|1] "" Vector__XXX SG_ STH_Zusatzheizung : 2|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ STH_LED : 3|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ STH_LED : 3|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ STH_Pumpe_ein : 4|1@1+ (1,0) [0|1] "" Vector__XXX SG_ STH_Geblaese : 5|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ STH_EKP_Anst : 6|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ STH_EKP_Anst : 6|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ STH_Start_folgt : 7|1@1+ (1,0) [0|1] "" Vector__XXX SG_ STH_Ventiloeffnungszeit : 8|6@1+ (1,0) [0|63] "Unit_Minut" Vector__XXX SG_ STH_Ventil_Status : 14|1@1+ (1,0) [0|1] "" Vector__XXX @@ -1067,15 +1054,15 @@ BO_ 1313 STH_01: 8 Gateway_MQB SG_ STH_Fehlerstatus : 37|3@1+ (1,0) [0|7] "" Vector__XXX SG_ STH_Heizleistung : 40|8@1+ (1,0) [0|255] "" Vector__XXX SG_ STH_Wassertemp : 48|8@1+ (0.75,-40) [-40|142.25] "Unit_DegreCelsi" Vector__XXX - SG_ STH_Motorvorwaermung : 59|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ STH_Motorvorwaermung : 59|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ STH_Servicemode : 60|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ STH_war_aktiv : 61|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ STH_war_aktiv : 61|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ STH_KVS_Ueberlauf : 62|1@1+ (1,0) [0|1] "" Vector__XXX SG_ STH_KD_Fehler : 63|1@1+ (1,0) [0|1] "" Vector__XXX BO_ 1172 STS_01: 8 Gateway_MQB - SG_ STS_01_CRC : 0|8@1+ (1,0) [0|255] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB - SG_ STS_01_BZ : 8|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ STS_01_CRC : 0|8@1+ (1,0) [0|255] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ STS_01_BZ : 8|4@1+ (1,0) [0|15] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ STS_Car_not_under_theft : 12|1@1+ (1,0) [0|1] "" Vector__XXX SG_ STS_Car_under_theft : 13|1@1+ (1,0) [0|1] "" Vector__XXX SG_ STS_Anlassersperre : 15|1@1+ (1,0) [0|1] "" Vector__XXX @@ -1090,15 +1077,15 @@ BO_ 1172 STS_01: 8 Gateway_MQB SG_ STS_Alarm_Blinker : 50|1@1+ (1,0) [0|1] "" Vector__XXX SG_ STS_Notstart : 51|1@1+ (1,0) [0|1] "" Vector__XXX SG_ STS_Signalhorn : 55|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ STS_Leerlaufschaltung : 56|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ STS_Leerlaufschaltung : 56|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB BO_ 1413 Systeminfo_01: 8 Gateway_MQB SG_ SI_Sammel_SG_Fehler : 0|6@1+ (1,0) [0|60] "" Vector__XXX SG_ SI_Rollenmode : 6|2@1+ (1,0) [0|3] "" Vector__XXX - SG_ SI_QRS_Mode : 8|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB + SG_ SI_QRS_Mode : 8|1@1+ (1,0) [0|1] "" Motor_Diesel_MQB,Motor_Hybrid_MQB,Motor_Otto_MQB SG_ SI_T_Mode : 9|1@1+ (1,0) [0|1] "" Vector__XXX - SG_ SI_NWDF : 10|1@1+ (1,0) [0|1] "" SAK_MQB - SG_ SI_NWDF_gueltig : 11|1@1+ (1,0) [0|1] "" SAK_MQB + SG_ SI_NWDF : 10|1@1+ (1,0) [0|1] "" SAK_MQB + SG_ SI_NWDF_gueltig : 11|1@1+ (1,0) [0|1] "" SAK_MQB SG_ SI_Sammelfehler : 12|1@1+ (1,0) [0|1] "" Vector__XXX SG_ GW_KD_Fehler : 13|1@1+ (1,0) [0|1] "" Vector__XXX SG_ SI_BUS_01 : 16|1@1+ (1,0) [0|1] "" Vector__XXX @@ -1118,75 +1105,175 @@ BO_ 1413 Systeminfo_01: 8 Gateway_MQB SG_ SI_BUS_15 : 30|1@1+ (1,0) [0|1] "" Vector__XXX BO_ 288 TSK_06: 8 Motor_Diesel_MQB - SG_ TSK_06_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ TSK_06_BZ : 8|4@1+ (1,0) [0|15] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ TSK_Radbremsmom : 12|12@1+ (8,0) [0|32760] "Unit_NewtoMeter" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ TSK_Status : 24|3@1+ (1,0) [0|7] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ TSK_v_Begrenzung_aktiv : 27|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ TSK_Standby_Anf_ESP : 28|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ TSK_Freig_Verzoeg_Anf : 30|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ TSK_Limiter_ausgewaehlt : 31|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ TSK_ax_Getriebe_02 : 48|9@1+ (0.024,-2.016) [-2.016|10.224] "Unit_MeterPerSeconSquar" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ TSK_Zwangszusch_ESP : 57|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ TSK_zul_Regelabw : 58|6@1+ (0.024,0) [0|1.512] "Unit_MeterPerSeconSquar" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ TSK_06_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ TSK_06_BZ : 8|4@1+ (1,0) [0|15] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ TSK_Radbremsmom : 12|12@1+ (8,0) [0|32760] "Unit_NewtoMeter" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ TSK_Status : 24|3@1+ (1,0) [0|7] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ TSK_v_Begrenzung_aktiv : 27|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ TSK_Standby_Anf_ESP : 28|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ TSK_Freig_Verzoeg_Anf : 30|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ TSK_Limiter_ausgewaehlt : 31|1@1+ (1,0) [0|1] "" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ TSK_ax_Getriebe_02 : 48|9@1+ (0.024,-2.016) [-2.016|10.224] "Unit_MeterPerSeconSquar" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ TSK_Zwangszusch_ESP : 57|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ TSK_zul_Regelabw : 58|6@1+ (0.024,0) [0|1.512] "Unit_MeterPerSeconSquar" Gateway_MQB,Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB BO_ 798 TSK_07: 8 Motor_Diesel_MQB - SG_ TSK_07_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB - SG_ TSK_07_BZ : 8|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ TSK_Wunschgeschw : 12|10@1+ (0.32,0) [0|326.72] "Unit_KiloMeterPerHour" Gateway_MQB - SG_ TSK_Texte_Primaeranz : 48|5@1+ (1,0) [0|31] "" Gateway_MQB - SG_ TSK_Limiter_Anzeige : 55|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ TSK_Status_Anzeige : 61|3@1+ (1,0) [0|7] "" Gateway_MQB + SG_ TSK_07_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB + SG_ TSK_07_BZ : 8|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ TSK_Wunschgeschw : 12|10@1+ (0.32,0) [0|326.72] "Unit_KiloMeterPerHour" Gateway_MQB + SG_ TSK_Texte_Primaeranz : 48|5@1+ (1,0) [0|31] "" Gateway_MQB + SG_ TSK_Limiter_Anzeige : 55|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ TSK_Status_Anzeige : 61|3@1+ (1,0) [0|7] "" Gateway_MQB BO_ 1716 VIN_01: 8 Gateway_MQB - SG_ VIN_01_MUX M : 0|2@1+ (1,0) [0|3] "" Airbag_MQB - SG_ KS_Geheimnis_1 m0 : 8|8@1+ (1,0) [0|255] "" Vector__XXX - SG_ VIN_4 m1 : 8|8@1+ (1,0) [0|255] "" Airbag_MQB - SG_ VIN_11 m2 : 8|8@1+ (1,0) [0|255] "" Airbag_MQB - SG_ KS_Geheimnis_2 m0 : 16|8@1+ (1,0) [0|255] "" Vector__XXX - SG_ VIN_5 m1 : 16|8@1+ (1,0) [0|255] "" Airbag_MQB - SG_ VIN_12 m2 : 16|8@1+ (1,0) [0|255] "" Airbag_MQB - SG_ KS_Geheimnis_3 m0 : 24|8@1+ (1,0) [0|255] "" Vector__XXX - SG_ VIN_6 m1 : 24|8@1+ (1,0) [0|255] "" Airbag_MQB - SG_ VIN_13 m2 : 24|8@1+ (1,0) [0|255] "" Airbag_MQB - SG_ KS_Geheimnis_4 m0 : 32|8@1+ (1,0) [0|255] "" Vector__XXX - SG_ VIN_7 m1 : 32|8@1+ (1,0) [0|255] "" Airbag_MQB - SG_ VIN_14 m2 : 32|8@1+ (1,0) [0|255] "" Airbag_MQB - SG_ VIN_1 m0 : 40|8@1+ (1,0) [0|255] "" Airbag_MQB - SG_ VIN_8 m1 : 40|8@1+ (1,0) [0|255] "" Airbag_MQB - SG_ VIN_15 m2 : 40|8@1+ (1,0) [0|255] "" Airbag_MQB - SG_ VIN_2 m0 : 48|8@1+ (1,0) [0|255] "" Airbag_MQB - SG_ VIN_9 m1 : 48|8@1+ (1,0) [0|255] "" Airbag_MQB - SG_ VIN_16 m2 : 48|8@1+ (1,0) [0|255] "" Airbag_MQB - SG_ VIN_3 m0 : 56|8@1+ (1,0) [0|255] "" Airbag_MQB - SG_ VIN_10 m1 : 56|8@1+ (1,0) [0|255] "" Airbag_MQB - SG_ VIN_17 m2 : 56|8@1+ (1,0) [0|255] "" Airbag_MQB BO_ 175 Waehlhebel_03: 4 Waehlhebel_MQB - SG_ WH_Status_Sperre : 0|3@1+ (1,0) [0|7] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ WH_Initialisierung : 3|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ WH_SensorPos_roh : 4|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ WH_03_BZ : 8|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ WH_SensorPos_roh_inv : 12|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ WH_Testergebnis : 16|8@1+ (1,0) [0|255] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ WH_Test_Aktiv : 24|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB - SG_ WH_Status : 25|7@1+ (1,0) [0|127] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ WH_Status_Sperre : 0|3@1+ (1,0) [0|7] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ WH_Initialisierung : 3|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ WH_SensorPos_roh : 4|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ WH_03_BZ : 8|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ WH_SensorPos_roh_inv : 12|4@1+ (1,0) [0|15] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ WH_Testergebnis : 16|8@1+ (1,0) [0|255] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ WH_Test_Aktiv : 24|1@1+ (1,0) [0|1] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB + SG_ WH_Status : 25|7@1+ (1,0) [0|127] "" Getriebe_DQ_Hybrid_MQB,Getriebe_DQ_MQB BO_ 916 WBA_03: 8 Getriebe_DQ_Hybrid_MQB - SG_ WBA_03_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB - SG_ WBA_03_BZ : 8|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ WBA_Fahrstufe_02 : 12|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ WBA_ZielFahrstufe : 16|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ WBA_GE_Warnung_02 : 20|4@1+ (1,0) [0|15] "" Gateway_MQB - SG_ WBA_eing_Gang_02 : 24|4@1+ (1,0) [0|15] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Otto_MQB - SG_ WBA_GE_Texte : 28|3@1+ (1,0) [0|7] "" Gateway_MQB - SG_ WBA_Segeln_aktiv : 31|1@1+ (1,0) [0|1] "" Gateway_MQB - SG_ WBA_Schaltschema : 32|5@1+ (1,0) [0|31] "" Gateway_MQB + SG_ WBA_03_CRC : 0|8@1+ (1,0) [0|255] "" Gateway_MQB + SG_ WBA_03_BZ : 8|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ WBA_Fahrstufe_02 : 12|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ WBA_ZielFahrstufe : 16|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ WBA_GE_Warnung_02 : 20|4@1+ (1,0) [0|15] "" Gateway_MQB + SG_ WBA_eing_Gang_02 : 24|4@1+ (1,0) [0|15] "" Gateway_MQB,Motor_Diesel_MQB,Motor_Otto_MQB + SG_ WBA_GE_Texte : 28|3@1+ (1,0) [0|7] "" Gateway_MQB + SG_ WBA_Segeln_aktiv : 31|1@1+ (1,0) [0|1] "" Gateway_MQB + SG_ WBA_Schaltschema : 32|5@1+ (1,0) [0|31] "" Gateway_MQB BO_ 1602 WIV_01: 8 Motor_Diesel_MQB - SG_ WIV_Verschleissindex : 0|16@1+ (2E-008,0) [0|0.00131068] "" Gateway_MQB - SG_ WIV_Russindex : 16|16@1+ (2E-008,0) [0|0.00131068] "" Gateway_MQB - SG_ WIV_t_min : 32|6@1+ (1,0) [0|63] "Unit_Month" Gateway_MQB - SG_ WIV_t_max : 40|6@1+ (1,0) [0|63] "Unit_Month" Gateway_MQB - SG_ WIV_W_min : 48|7@1+ (1000,0) [0|127000] "Unit_KiloMeter" Gateway_MQB - SG_ WIV_W_max : 56|7@1+ (1000,0) [0|127000] "Unit_KiloMeter" Gateway_MQB + SG_ WIV_Verschleissindex : 0|16@1+ (2e-8,0) [0|0.00131068] "" Gateway_MQB + SG_ WIV_Russindex : 16|16@1+ (2e-8,0) [0|0.00131068] "" Gateway_MQB + SG_ WIV_t_min : 32|6@1+ (1,0) [0|63] "Unit_Month" Gateway_MQB + SG_ WIV_t_max : 40|6@1+ (1,0) [0|63] "Unit_Month" Gateway_MQB + SG_ WIV_W_min : 48|7@1+ (1000,0) [0|127000] "Unit_KiloMeter" Gateway_MQB + SG_ WIV_W_max : 56|7@1+ (1000,0) [0|127000] "Unit_KiloMeter" Gateway_MQB + +BO_ 294 HCA_01: 8 XXX + SG_ 3 : 15|4@0+ (1,0) [0|15] "" XXX + SG_ 7 : 55|8@0+ (1,0) [0|255] "" XXX + SG_ 254 : 47|8@0+ (1,0) [0|255] "" XXX + SG_ HCA_01_CRC : 7|8@0+ (1,0) [0|255] "" XXX + SG_ HCA_01_BZ : 11|4@0+ (1,0) [0|255] "" XXX + SG_ Assist_Requested : 30|1@0+ (1,0) [0|1] "" XXX + SG_ Assist_Torque : 16|14@1+ (1,0) [0|300] "Nm" XXX + SG_ Assist_VZ : 31|1@0+ (1,0) [0|1] "" XXX + SG_ HCA_Available : 32|1@1+ (1,0) [0|1] "" XXX + SG_ HCA_Standby : 33|1@0+ (1,0) [0|1] "" XXX + SG_ HCA_Active : 34|1@0+ (1,0) [0|1] "" XXX + +BO_ 159 EPS_01: 8 XXX + SG_ EPS_01_CRC : 0|8@1+ (1,0) [0|255] "" XXX + SG_ EPS_01_BZ : 8|4@1+ (1,0) [0|15] "" XXX + SG_ Steering_Wheel_Angle : 16|13@1+ (0.075,0) [0|16383] "Unit_DegreOfArc" XXX + SG_ Steering_Wheel_Angle_VZ : 31|1@0+ (1,0) [0|1] "" XXX + SG_ HCA_Active : 34|1@0+ (1,0) [0|1] "" XXX + SG_ HCA_Standby : 33|1@0+ (1,0) [0|1] "" XXX + SG_ Unknown_Status2 : 63|1@0+ (1,0) [0|1] "" XXX + SG_ HCA_Ready : 32|1@1+ (1,0) [0|3] "" XXX + SG_ Driver_Strain : 40|13@1+ (1,0) [0|255] "Nm" XXX + SG_ Driver_Strain_VZ : 55|1@1+ (1,0) [0|1] "" XXX + SG_ Unknown_Status1 : 62|1@0+ (1,0) [0|1] "" XXX + +BO_ 286 VehicleSpeed: 8 XXX + SG_ VehicleSpeed_CRC : 0|8@1+ (1,0) [0|255] "" XXX + SG_ VehicleSpeed_BZ : 8|4@1+ (1,0) [0|15] "" XXX + SG_ Speed : 52|12@1+ (0.125,0) [0|1] "" XXX + +BO_ 919 LDW_02: 8 XXX + SG_ LDW_DLC : 40|8@1+ (0.01,0) [0|255] "m" XXX + SG_ LDW_TLC : 48|5@1+ (0.05,0) [0|255] "Seconds" XXX + SG_ LDW_Unknown : 15|2@0+ (1,0) [0|3] "" XXX + SG_ Alert_Message : 16|4@1+ (1,0) [0|15] "" XXX + SG_ LDW_Direction : 20|1@0+ (1,0) [0|1] "" XXX + SG_ Right_Lane_Status : 36|2@1+ (1,0) [0|3] "" XXX + SG_ Left_Lane_Status : 38|2@1+ (1,0) [0|3] "" XXX + SG_ Kombi_Lamp_Orange : 61|1@0+ (1,0) [0|1] "" XXX + SG_ Kombi_Lamp_Green : 62|1@0+ (1,0) [0|1] "" XXX + +BO_ 780 ACC_02: 8 XXX + SG_ Kollision1 : 23|1@1+ (1,0) [0|1] "" XXX + SG_ ACC_MinusInv : 36|2@1+ (1,0) [0|3] "" XXX + SG_ ACC_Minus : 38|2@1+ (1,0) [0|3] "" XXX + SG_ Kollision2 : 40|1@1+ (1,0) [0|1] "" XXX + SG_ MotorbitB5_1 : 41|1@1+ (1,0) [0|1] "" XXX + SG_ 1_aktivieren : 42|1@1+ (1,0) [0|1] "" XXX + SG_ Tacho_LED : 43|1@1+ (1,0) [0|1] "" XXX + SG_ Hebelquit : 44|1@1+ (1,0) [0|1] "" XXX + SG_ 1_aktivieren_inv : 45|1@1+ (1,0) [0|1] "" XXX + SG_ Folgefahrt : 46|1@1+ (1,0) [0|1] "" XXX + SG_ MotorbitB5_7 : 47|1@1+ (1,0) [0|1] "" XXX + SG_ SetAbstand : 48|4@1+ (1,0) [0|15] "" XXX + SG_ Hebel : 56|4@1+ (1,0) [0|15] "" XXX + SG_ SetSpeed : 12|10@1+ (0.32,0) [0|320] "kmh" XXX + SG_ Abstand : 24|10@1+ (0.1,0) [0|102.3] "m" XXX + SG_ ACC_02_CRC : 0|8@1+ (1,0) [0|255] "" XXX + SG_ ACC_02_BZ : 8|4@1+ (1,0) [0|15] "" XXX + +BO_ 302 ACC_07: 8 XXX + SG_ ACC_07_BZ : 8|4@1+ (1,0) [0|15] "" XXX + SG_ ACC_07_CRC : 0|8@1+ (1,0) [0|255] "" XXX + +BO_ 264 Fahrwerk_01: 8 XXX + SG_ Fahrwerk_01_BZ : 8|4@1+ (1,0) [0|15] "" XXX + SG_ Fahrwerk_01_CRC : 0|8@1+ (1,0) [0|255] "" XXX + +BO_ 695 RCTA_01: 8 XXX + SG_ RCTA_01_BZ : 8|4@1+ (1,0) [0|15] "" XXX + SG_ RCTA_01_CRC : 0|8@1+ (1,0) [0|255] "" XXX + +BO_ 783 SWA_01: 8 XXX + SG_ SWA_01_BZ : 8|4@1+ (1,0) [0|15] "" XXX + SG_ SWA_01_CRC : 0|8@1+ (1,0) [0|255] "" XXX + +BO_ 804 ACC_04: 8 XXX + SG_ ACC_04_CRC : 0|8@1+ (1,0) [0|255] "" XXX + SG_ ACC_04_BZ : 8|4@1+ (1,0) [0|15] "" XXX + +BO_ 917 LWR_AFS_01: 8 XXX + +BO_ 991 Gateway_76: 8 XXX + +BO_ 997 TSG_FT_02: 8 XXX + SG_ TSG_FT_02_BZ : 8|4@1+ (1,0) [0|15] "" XXX + SG_ TSG_FT_02_CRC : 0|8@1+ (1,0) [0|255] "" XXX + +BO_ 1175 Parkhilfe_01: 8 XXX + +BO_ 427 ESP_33: 8 XXX + SG_ ESP_33_BZ : 8|4@1+ (1,0) [0|15] "" XXX + SG_ ESP_33_CRC : 0|8@1+ (1,0) [0|255] "" XXX + + + + +CM_ SG_ 294 3 "May be zero when sent by older cameras"; +CM_ SG_ 294 7 "May be zero when sent by older cameras"; +CM_ SG_ 294 254 "May be zero when sent by older cameras"; +CM_ SG_ 294 Assist_Torque "Heading control input, torque"; +CM_ SG_ 294 Assist_VZ "Heading control input, direction (sign)"; +CM_ SG_ 294 HCA_Available "Must be 1 for steering rack to accept HCA commands"; +CM_ SG_ 159 HCA_Ready "1 if HCA is okay, 0 if the rack doesn't have HCA configured or a timer/constraint has been violated, rack will not respond to HCA commands"; +CM_ SG_ 159 Driver_Strain "Steering input by driver, torque"; +CM_ SG_ 159 Driver_Strain_VZ "Steering input by driver, sign (direction)"; +CM_ SG_ 919 LDW_DLC "Probable DLC (distance to line crossing)"; +CM_ SG_ 919 LDW_TLC "Probable TLC (time to line crossing)"; +CM_ SG_ 919 LDW_Unknown "Might be a steering pressed / driver active flag"; +CM_ SG_ 919 Alert_Message "Static table of alert messages to be invoked in the instrument cluster, some with or without beeps, 0 = no current message"; +CM_ SG_ 919 LDW_Direction "Left/right indicator for DLC and TLC"; +CM_ SG_ 919 Right_Lane_Status "Display brightness range, 0 = no lane, 3 = full brightness"; +CM_ SG_ 919 Left_Lane_Status "Display brightness range, 0 = no lane, 3 = full brightness"; +CM_ SG_ 919 Kombi_Lamp_Orange "Enables orange LDW light in instrument cluster"; +CM_ SG_ 919 Kombi_Lamp_Green "Enables green LDW light in instrument cluster"; +CM_ SG_ 780 Folgefahrt "Following another vehicle"; +CM_ SG_ 780 SetAbstand "Set following distance"; +CM_ SG_ 780 SetSpeed "ACC set speed"; +CM_ SG_ 780 Abstand "Following distance"; +VAL_ 173 GE_Fahrstufe 5 "P" 6 "R" 7 "N" 8 "D" 9 "S" 10 "E" 14 "T" ; diff --git a/panda/.circleci/config.yml b/panda/.circleci/config.yml index 6b98610c5..06dae5735 100644 --- a/panda/.circleci/config.yml +++ b/panda/.circleci/config.yml @@ -12,6 +12,37 @@ jobs: name: Run safety test command: | docker run panda_safety /bin/bash -c "cd /panda/tests/safety; ./test.sh" + + misra-c2012: + machine: + docker_layer_caching: true + steps: + - checkout + - run: + name: Build image + command: "docker build -t panda_misra -f tests/misra/Dockerfile ." + - run: + name: Run Misra C 2012 test + command: | + mkdir /tmp/misra + docker run -v /tmp/misra:/tmp/misra panda_misra /bin/bash -c "cd /panda/tests/misra; ./test_misra.sh" + - store_artifacts: + name: Store misra test output + path: /tmp/misra/output.txt + + strict-compiler: + machine: + docker_layer_caching: true + steps: + - checkout + - run: + name: Build image + command: "docker build -t panda_strict_compiler -f tests/build_strict/Dockerfile ." + - run: + name: Build Panda with strict compiler rules + command: | + docker run panda_strict_compiler /bin/bash -c "cd /panda/board; make -f Makefile.strict clean; make -f Makefile.strict bin" + build: machine: docker_layer_caching: true @@ -40,10 +71,6 @@ jobs: name: Build Pedal STM bootstub image command: | docker run panda_build /bin/bash -c "cd /panda/board/pedal; make obj/bootstub.bin" - - run: - name: Build NEO STM image - command: | - docker run panda_build /bin/bash -c "cd /panda/board; make clean; make -f Makefile.legacy obj/comma.bin" - run: name: Build ESP image command: | @@ -54,4 +81,6 @@ workflows: main: jobs: - safety + - misra-c2012 + - strict-compiler - build diff --git a/panda/.gitignore b/panda/.gitignore index 7b7762ef4..70d010fab 100644 --- a/panda/.gitignore +++ b/panda/.gitignore @@ -10,5 +10,6 @@ a.out dist/ pandacan.egg-info/ board/obj/ -examples/output.csv -.DS_Store +examples/output.csv +.DS_Store +nosetests.xml diff --git a/panda/Dockerfile b/panda/Dockerfile index 100509f51..1a0d92466 100644 --- a/panda/Dockerfile +++ b/panda/Dockerfile @@ -59,6 +59,4 @@ USER pandauser RUN cd /tmp/panda/boardesp && ./get_sdk_ci.sh USER root -COPY ./xx/pandaextra /tmp/pandaextra - ADD ./panda.tar.gz /tmp/panda diff --git a/panda/Jenkinsfile b/panda/Jenkinsfile index c67a10051..0a861a5fa 100644 --- a/panda/Jenkinsfile +++ b/panda/Jenkinsfile @@ -14,8 +14,6 @@ pipeline { steps { timeout(time: 60, unit: 'MINUTES') { script { - sh 'git clone --no-checkout --depth 1 git@github.com:commaai/xx.git || true' - sh 'cd xx && git fetch origin && git checkout origin/master -- pandaextra && cd ..' // Needed for certs for panda flashing sh 'git archive -v -o panda.tar.gz --format=tar.gz HEAD' dockerImage = docker.build("${env.DOCKER_IMAGE_TAG}") } diff --git a/panda/VERSION b/panda/VERSION index 24e56e03c..23c38c241 100644 --- a/panda/VERSION +++ b/panda/VERSION @@ -1 +1 @@ -v1.2.1 \ No newline at end of file +v1.3.1 \ No newline at end of file diff --git a/panda/board/Makefile.legacy b/panda/board/Makefile.legacy deleted file mode 100644 index f6f9f9f32..000000000 --- a/panda/board/Makefile.legacy +++ /dev/null @@ -1,9 +0,0 @@ -# :set noet -PROJ_NAME = comma -CFLAGS = -g -Wall - -CFLAGS += -mlittle-endian -mthumb -mcpu=cortex-m3 -CFLAGS += -msoft-float -DSTM32F2 -DSTM32F205xx -STARTUP_FILE = startup_stm32f205xx - -include build.mk diff --git a/panda/board/Makefile.strict b/panda/board/Makefile.strict new file mode 100644 index 000000000..b2ff83d30 --- /dev/null +++ b/panda/board/Makefile.strict @@ -0,0 +1,8 @@ +PROJ_NAME = panda +CFLAGS = -g -Wall -Wextra -pedantic -Wstrict-prototypes + +CFLAGS += -mlittle-endian -mthumb -mcpu=cortex-m4 +CFLAGS += -mhard-float -DSTM32F4 -DSTM32F413xx -mfpu=fpv4-sp-d16 -fsingle-precision-constant +STARTUP_FILE = startup_stm32f413xx + +include build.mk diff --git a/panda/board/README.md b/panda/board/README.md index b3be654be..5fe2e4b23 100644 --- a/panda/board/README.md +++ b/panda/board/README.md @@ -23,12 +23,6 @@ Programming make ``` -**NEO** - -``` -make -f Makefile.legacy -``` - Troubleshooting ---- diff --git a/panda/board/bootstub.c b/panda/board/bootstub.c index e44986c29..6fcb386de 100644 --- a/panda/board/bootstub.c +++ b/panda/board/bootstub.c @@ -12,11 +12,14 @@ #include "stm32f2xx_hal_gpio_ex.h" #endif +// default since there's no serial +int puts(const char *a) { return 0; } +void puth(unsigned int i) {} + #include "libc.h" #include "provision.h" -#include "drivers/drivers.h" - +#include "drivers/clock.h" #include "drivers/llgpio.h" #include "gpio.h" @@ -24,15 +27,6 @@ #include "drivers/usb.h" //#include "drivers/uart.h" -#ifdef PEDAL -#define CUSTOM_CAN_INTERRUPTS -#include "safety.h" -#include "drivers/can.h" -#endif - -int puts(const char *a) { return 0; } -void puth(unsigned int i) {} - #include "crypto/rsa.h" #include "crypto/sha.h" diff --git a/panda/board/drivers/can.h b/panda/board/drivers/can.h index 9f02c2eba..43e4d41de 100644 --- a/panda/board/drivers/can.h +++ b/panda/board/drivers/can.h @@ -1,10 +1,38 @@ -// IRQs: CAN1_TX, CAN1_RX0, CAN1_SCE, CAN2_TX, CAN2_RX0, CAN2_SCE, CAN3_TX, CAN3_RX0, CAN3_SCE +// IRQs: CAN1_TX, CAN1_RX0, CAN1_SCE +// CAN2_TX, CAN2_RX0, CAN2_SCE +// CAN3_TX, CAN3_RX0, CAN3_SCE + +typedef struct { + uint32_t w_ptr; + uint32_t r_ptr; + uint32_t fifo_size; + CAN_FIFOMailBox_TypeDef *elems; +} can_ring; + +#define CAN_BUS_RET_FLAG 0x80 +#define CAN_BUS_NUM_MASK 0x7F + +#define BUS_MAX 4 + +extern int can_live, pending_can_live; + +// must reinit after changing these +extern int can_loopback, can_silent; +extern uint32_t can_speed[]; + +void can_set_forwarding(int from, int to); + +void can_init(uint8_t can_number); +void can_init_all(); +void can_send(CAN_FIFOMailBox_TypeDef *to_push, uint8_t bus_number); +int can_pop(can_ring *q, CAN_FIFOMailBox_TypeDef *elem); + +// end API + #define ALL_CAN_SILENT 0xFF #define ALL_CAN_BUT_MAIN_SILENT 0xFE #define ALL_CAN_LIVE 0 -#include "lline_relay.h" - int can_live = 0, pending_can_live = 0, can_loopback = 0, can_silent = ALL_CAN_SILENT; // ********************* instantiate queues ********************* @@ -16,19 +44,9 @@ int can_live = 0, pending_can_live = 0, can_loopback = 0, can_silent = ALL_CAN_S can_buffer(rx_q, 0x1000) can_buffer(tx1_q, 0x100) can_buffer(tx2_q, 0x100) - -#ifdef PANDA - can_buffer(tx3_q, 0x100) - can_buffer(txgmlan_q, 0x100) - can_ring *can_queues[] = {&can_tx1_q, &can_tx2_q, &can_tx3_q, &can_txgmlan_q}; -#else - can_ring *can_queues[] = {&can_tx1_q, &can_tx2_q}; -#endif - -#ifdef PANDA -// Forward declare -void power_save_reset_timer(); -#endif +can_buffer(tx3_q, 0x100) +can_buffer(txgmlan_q, 0x100) +can_ring *can_queues[] = {&can_tx1_q, &can_tx2_q, &can_tx3_q, &can_txgmlan_q}; // ********************* interrupt safe queue ********************* @@ -85,76 +103,20 @@ int can_tx_cnt = 0; int can_txd_cnt = 0; int can_err_cnt = 0; -// NEO: Bus 1=CAN1 Bus 2=CAN2 // Panda: Bus 0=CAN1 Bus 1=CAN2 Bus 2=CAN3 -#ifdef PANDA - CAN_TypeDef *cans[] = {CAN1, CAN2, CAN3}; - uint8_t bus_lookup[] = {0,1,2}; - uint8_t can_num_lookup[] = {0,1,2,-1}; - int8_t can_forwarding[] = {-1,-1,-1,-1}; - uint32_t can_speed[] = {5000, 5000, 5000, 333}; - bool can_autobaud_enabled[] = {false, false, false, false}; - #define CAN_MAX 3 -#else - CAN_TypeDef *cans[] = {CAN1, CAN2}; - uint8_t bus_lookup[] = {1,0}; - uint8_t can_num_lookup[] = {1,0}; - int8_t can_forwarding[] = {-1,-1}; - uint32_t can_speed[] = {5000, 5000}; - bool can_autobaud_enabled[] = {false, false}; - #define CAN_MAX 2 -#endif - -uint32_t can_autobaud_speeds[] = {5000, 2500, 1250, 1000, 10000}; -#define AUTOBAUD_SPEEDS_LEN (sizeof(can_autobaud_speeds) / sizeof(can_autobaud_speeds[0])) +CAN_TypeDef *cans[] = {CAN1, CAN2, CAN3}; +uint8_t bus_lookup[] = {0,1,2}; +uint8_t can_num_lookup[] = {0,1,2,-1}; +int8_t can_forwarding[] = {-1,-1,-1,-1}; +uint32_t can_speed[] = {5000, 5000, 5000, 333}; +#define CAN_MAX 3 #define CANIF_FROM_CAN_NUM(num) (cans[num]) -#ifdef PANDA #define CAN_NUM_FROM_CANIF(CAN) (CAN==CAN1 ? 0 : (CAN==CAN2 ? 1 : 2)) #define CAN_NAME_FROM_CANIF(CAN) (CAN==CAN1 ? "CAN1" : (CAN==CAN2 ? "CAN2" : "CAN3")) -#else -#define CAN_NUM_FROM_CANIF(CAN) (CAN==CAN1 ? 0 : 1) -#define CAN_NAME_FROM_CANIF(CAN) (CAN==CAN1 ? "CAN1" : "CAN2") -#endif #define BUS_NUM_FROM_CAN_NUM(num) (bus_lookup[num]) #define CAN_NUM_FROM_BUS_NUM(num) (can_num_lookup[num]) -// other option -/*#define CAN_QUANTA 16 -#define CAN_SEQ1 13 -#define CAN_SEQ2 2*/ - -// this is needed for 1 mbps support -#define CAN_QUANTA 8 -#define CAN_SEQ1 6 // roundf(quanta * 0.875f) - 1; -#define CAN_SEQ2 1 // roundf(quanta * 0.125f); - -#define CAN_PCLK 24000 -// 333 = 33.3 kbps -// 5000 = 500 kbps -#define can_speed_to_prescaler(x) (CAN_PCLK / CAN_QUANTA * 10 / (x)) - -void can_autobaud_speed_increment(uint8_t can_number) { - uint32_t autobaud_speed = can_autobaud_speeds[0]; - uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number); - for (int i = 0; i < AUTOBAUD_SPEEDS_LEN; i++) { - if (can_speed[bus_number] == can_autobaud_speeds[i]) { - if (i+1 < AUTOBAUD_SPEEDS_LEN) { - autobaud_speed = can_autobaud_speeds[i+1]; - } - break; - } - } - can_speed[bus_number] = autobaud_speed; -#ifdef DEBUG - CAN_TypeDef* CAN = CANIF_FROM_CAN_NUM(can_number); - puts(CAN_NAME_FROM_CANIF(CAN)); - puts(" auto-baud test "); - putui(can_speed[bus_number]); - puts(" cbps\n"); -#endif -} - void process_can(uint8_t can_number); void can_set_speed(uint8_t can_number) { @@ -162,41 +124,14 @@ void can_set_speed(uint8_t can_number) { uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number); while (true) { - // initialization mode - CAN->MCR = CAN_MCR_TTCM | CAN_MCR_INRQ; - while((CAN->MSR & CAN_MSR_INAK) != CAN_MSR_INAK); - - // set time quanta from defines - CAN->BTR = (CAN_BTR_TS1_0 * (CAN_SEQ1-1)) | - (CAN_BTR_TS2_0 * (CAN_SEQ2-1)) | - (can_speed_to_prescaler(can_speed[bus_number]) - 1); - - // silent loopback mode for debugging - if (can_loopback) { - CAN->BTR |= CAN_BTR_SILM | CAN_BTR_LBKM; - } - if (can_silent & (1 << can_number)) { - CAN->BTR |= CAN_BTR_SILM; - } - - // reset - CAN->MCR = CAN_MCR_TTCM | CAN_MCR_ABOM; - - #define CAN_TIMEOUT 1000000 - int tmp = 0; - while((CAN->MSR & CAN_MSR_INAK) == CAN_MSR_INAK && tmp < CAN_TIMEOUT) tmp++; - if (tmp < CAN_TIMEOUT) { + if (llcan_set_speed(CAN, can_speed[bus_number], can_loopback, can_silent & (1 << can_number))) { return; } - if (can_autobaud_enabled[bus_number]) { - can_autobaud_speed_increment(can_number); - } else { - puts("CAN init FAILED!!!!!\n"); - puth(can_number); puts(" "); - puth(BUS_NUM_FROM_CAN_NUM(can_number)); puts("\n"); - return; - } + puts("CAN init FAILED!!!!!\n"); + puth(can_number); puts(" "); + puth(BUS_NUM_FROM_CAN_NUM(can_number)); puts("\n"); + return; } } @@ -207,40 +142,7 @@ void can_init(uint8_t can_number) { set_can_enable(CAN, 1); can_set_speed(can_number); - // accept all filter - CAN->FMR |= CAN_FMR_FINIT; - - // no mask - CAN->sFilterRegister[0].FR1 = 0; - CAN->sFilterRegister[0].FR2 = 0; - CAN->sFilterRegister[14].FR1 = 0; - CAN->sFilterRegister[14].FR2 = 0; - CAN->FA1R |= 1 | (1 << 14); - - CAN->FMR &= ~(CAN_FMR_FINIT); - - // enable certain CAN interrupts - CAN->IER |= CAN_IER_TMEIE | CAN_IER_FMPIE0 | CAN_IER_WKUIE; - - switch (can_number) { - case 0: - NVIC_EnableIRQ(CAN1_TX_IRQn); - NVIC_EnableIRQ(CAN1_RX0_IRQn); - NVIC_EnableIRQ(CAN1_SCE_IRQn); - break; - case 1: - NVIC_EnableIRQ(CAN2_TX_IRQn); - NVIC_EnableIRQ(CAN2_RX0_IRQn); - NVIC_EnableIRQ(CAN2_SCE_IRQn); - break; -#ifdef CAN3 - case 2: - NVIC_EnableIRQ(CAN3_TX_IRQn); - NVIC_EnableIRQ(CAN3_RX0_IRQn); - NVIC_EnableIRQ(CAN3_SCE_IRQn); - break; -#endif - } + llcan_init(CAN); // in case there are queued up messages process_can(can_number); @@ -253,7 +155,6 @@ void can_init_all() { } void can_set_gmlan(int bus) { - #ifdef PANDA if (bus == -1 || bus != can_num_lookup[3]) { // GMLAN OFF switch (can_num_lookup[3]) { @@ -284,7 +185,7 @@ void can_set_gmlan(int bus) { can_num_lookup[1] = -1; can_num_lookup[3] = 1; can_init(1); - } else if (bus == 2 && revision == PANDA_REV_C) { + } else if (bus == 2) { puts("GMLAN on CAN3\n"); // GMLAN on CAN3 set_can_mode(2, 1); @@ -293,7 +194,6 @@ void can_set_gmlan(int bus) { can_num_lookup[3] = 2; can_init(2); } - #endif } // CAN error @@ -319,34 +219,8 @@ void can_sce(CAN_TypeDef *CAN) { puts("\n"); #endif - uint8_t can_number = CAN_NUM_FROM_CANIF(CAN); - uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number); - - if (CAN->MSR & CAN_MSR_WKUI) { - //Waking from sleep - #ifdef DEBUG - puts("WAKE\n"); - #endif - set_can_enable(CAN, 1); - CAN->MSR &= ~(CAN_MSR_WKUI); - CAN->MSR = CAN->MSR; -#ifdef PANDA - power_save_reset_timer(); -#endif - } else { - can_err_cnt += 1; - - - if (can_autobaud_enabled[bus_number] && (CAN->ESR & CAN_ESR_LEC)) { - can_autobaud_speed_increment(can_number); - can_set_speed(can_number); - } - - // clear current send - CAN->TSR |= CAN_TSR_ABRQ0; - CAN->MSR &= ~(CAN_MSR_ERRI); - CAN->MSR = CAN->MSR; - } + can_err_cnt += 1; + llcan_clear_send(CAN); exit_critical_section(); } @@ -354,9 +228,6 @@ void can_sce(CAN_TypeDef *CAN) { void process_can(uint8_t can_number) { if (can_number == 0xff) return; -#ifdef PANDA - power_save_reset_timer(); -#endif enter_critical_section(); @@ -422,22 +293,9 @@ void process_can(uint8_t can_number) { // CAN receive handlers // blink blue when we are receiving CAN messages void can_rx(uint8_t can_number) { - #ifdef PANDA - power_save_reset_timer(); - #endif CAN_TypeDef *CAN = CANIF_FROM_CAN_NUM(can_number); uint8_t bus_number = BUS_NUM_FROM_CAN_NUM(can_number); while (CAN->RF0R & CAN_RF0R_FMP0) { - if (can_autobaud_enabled[bus_number]) { - can_autobaud_enabled[bus_number] = false; - puts(CAN_NAME_FROM_CANIF(CAN)); - #ifdef DEBUG - puts(" auto-baud "); - putui(can_speed[bus_number]); - puts(" cbps\n"); - #endif - } - can_rx_cnt += 1; // can is live @@ -454,25 +312,19 @@ void can_rx(uint8_t can_number) { to_push.RDTR = (to_push.RDTR & 0xFFFF000F) | (bus_number << 4); // forwarding (panda only) - #ifdef PANDA - if ((get_lline_status() != 0) || !relay_control) { //Relay engaged or relay isn't controlled, allow fwd - int bus_fwd_num = can_forwarding[bus_number] != -1 ? can_forwarding[bus_number] : safety_fwd_hook(bus_number, &to_push); - if (bus_fwd_num != -1) { - CAN_FIFOMailBox_TypeDef to_send; - to_send.RIR = to_push.RIR | 1; // TXRQ - to_send.RDTR = to_push.RDTR; - to_send.RDLR = to_push.RDLR; - to_send.RDHR = to_push.RDHR; - can_send(&to_send, bus_fwd_num); - } - } - #endif + int bus_fwd_num = can_forwarding[bus_number] != -1 ? can_forwarding[bus_number] : safety_fwd_hook(bus_number, &to_push); + if (bus_fwd_num != -1) { + CAN_FIFOMailBox_TypeDef to_send; + to_send.RIR = to_push.RIR | 1; // TXRQ + to_send.RDTR = to_push.RDTR; + to_send.RDLR = to_push.RDLR; + to_send.RDHR = to_push.RDHR; + can_send(&to_send, bus_fwd_num); + } safety_rx_hook(&to_push); - #ifdef PANDA - set_led(LED_BLUE, 1); - #endif + set_led(LED_BLUE, 1); can_push(&can_rx_q, &to_push); // next @@ -480,8 +332,6 @@ void can_rx(uint8_t can_number) { } } -#ifndef CUSTOM_CAN_INTERRUPTS - void CAN1_TX_IRQHandler() { process_can(0); } void CAN1_RX0_IRQHandler() { can_rx(0); } void CAN1_SCE_IRQHandler() { can_sce(CAN1); } @@ -490,25 +340,19 @@ void CAN2_TX_IRQHandler() { process_can(1); } void CAN2_RX0_IRQHandler() { can_rx(1); } void CAN2_SCE_IRQHandler() { can_sce(CAN2); } -#ifdef CAN3 void CAN3_TX_IRQHandler() { process_can(2); } void CAN3_RX0_IRQHandler() { can_rx(2); } void CAN3_SCE_IRQHandler() { can_sce(CAN3); } -#endif - -#endif void can_send(CAN_FIFOMailBox_TypeDef *to_push, uint8_t bus_number) { - if (safety_tx_hook(to_push) && !can_autobaud_enabled[bus_number]) { + if (safety_tx_hook(to_push)) { if (bus_number < BUS_MAX) { // add CAN packet to send queue // bus number isn't passed through to_push->RDTR &= 0xF; if (bus_number == 3 && can_num_lookup[3] == 0xFF) { - #ifdef PANDA // TODO: why uint8 bro? only int8? bitbang_gmlan(to_push); - #endif } else { can_push(can_queues[bus_number], to_push); process_can(CAN_NUM_FROM_BUS_NUM(bus_number)); @@ -520,3 +364,4 @@ void can_send(CAN_FIFOMailBox_TypeDef *to_push, uint8_t bus_number) { void can_set_forwarding(int from, int to) { can_forwarding[from] = to; } + diff --git a/panda/board/drivers/clock.h b/panda/board/drivers/clock.h new file mode 100644 index 000000000..c999c3f59 --- /dev/null +++ b/panda/board/drivers/clock.h @@ -0,0 +1,40 @@ +void clock_init() { + // enable external oscillator + RCC->CR |= RCC_CR_HSEON; + while ((RCC->CR & RCC_CR_HSERDY) == 0); + + // divide shit + RCC->CFGR = RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PPRE2_DIV2 | RCC_CFGR_PPRE1_DIV4; + + // 16mhz crystal + RCC->PLLCFGR = RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLM_3 | + RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_5 | RCC_PLLCFGR_PLLSRC_HSE; + + // start PLL + RCC->CR |= RCC_CR_PLLON; + while ((RCC->CR & RCC_CR_PLLRDY) == 0); + + // Configure Flash prefetch, Instruction cache, Data cache and wait state + // *** without this, it breaks *** + FLASH->ACR = FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_LATENCY_5WS; + + // switch to PLL + RCC->CFGR |= RCC_CFGR_SW_PLL; + while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL); + + // *** running on PLL *** +} + +void watchdog_init() { + // setup watchdog + IWDG->KR = 0x5555; + IWDG->PR = 0; // divider /4 + // 0 = 0.125 ms, let's have a 50ms watchdog + IWDG->RLR = 400 - 1; + IWDG->KR = 0xCCCC; +} + +void watchdog_feed() { + IWDG->KR = 0xAAAA; +} + diff --git a/panda/board/drivers/drivers.h b/panda/board/drivers/drivers.h deleted file mode 100644 index d3409d609..000000000 --- a/panda/board/drivers/drivers.h +++ /dev/null @@ -1,141 +0,0 @@ -#ifndef PANDA_DRIVERS_H -#define PANDA_DRIVERS_H - -// ********************* LLGPIO ********************* - -#define MODE_INPUT 0 -#define MODE_OUTPUT 1 -#define MODE_ALTERNATE 2 -#define MODE_ANALOG 3 - -#define PULL_NONE 0 -#define PULL_UP 1 -#define PULL_DOWN 2 - -void set_gpio_mode(GPIO_TypeDef *GPIO, int pin, int mode); -void set_gpio_output(GPIO_TypeDef *GPIO, int pin, int val); -void set_gpio_alternate(GPIO_TypeDef *GPIO, int pin, int mode); -void set_gpio_pullup(GPIO_TypeDef *GPIO, int pin, int mode); - -int get_gpio_input(GPIO_TypeDef *GPIO, int pin); - - -// ********************* USB ********************* -// IRQs: OTG_FS - -typedef union { - uint16_t w; - struct BW { - uint8_t msb; - uint8_t lsb; - } - bw; -} -uint16_t_uint8_t; - -typedef union _USB_Setup { - uint32_t d8[2]; - struct _SetupPkt_Struc - { - uint8_t bmRequestType; - uint8_t bRequest; - uint16_t_uint8_t wValue; - uint16_t_uint8_t wIndex; - uint16_t_uint8_t wLength; - } b; -} -USB_Setup_TypeDef; - -void usb_init(); -int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired); -int usb_cb_ep1_in(uint8_t *usbdata, int len, int hardwired); -void usb_cb_ep2_out(uint8_t *usbdata, int len, int hardwired); -void usb_cb_ep3_out(uint8_t *usbdata, int len, int hardwired); -void usb_cb_enumeration_complete(); - - -// ********************* UART ********************* -// IRQs: USART1, USART2, USART3, UART5 - -#define FIFO_SIZE 0x400 -typedef struct uart_ring { - uint16_t w_ptr_tx; - uint16_t r_ptr_tx; - uint8_t elems_tx[FIFO_SIZE]; - uint16_t w_ptr_rx; - uint16_t r_ptr_rx; - uint8_t elems_rx[FIFO_SIZE]; - USART_TypeDef *uart; - void (*callback)(struct uart_ring*); -} uart_ring; - -void uart_init(USART_TypeDef *u, int baud); - -int getc(uart_ring *q, char *elem); -int putc(uart_ring *q, char elem); - -int puts(const char *a); -void puth(unsigned int i); -void hexdump(const void *a, int l); - - -// ********************* ADC ********************* - -void adc_init(); -uint32_t adc_get(int channel); - - -// ********************* DAC ********************* - -void dac_init(); -void dac_set(int channel, uint32_t value); - - -// ********************* TIMER ********************* - -void timer_init(TIM_TypeDef *TIM, int psc); - - -// ********************* SPI ********************* -// IRQs: DMA2_Stream2, DMA2_Stream3, EXTI4 - -void spi_init(); -int spi_cb_rx(uint8_t *data, int len, uint8_t *data_out); - - -// ********************* CAN ********************* -// IRQs: CAN1_TX, CAN1_RX0, CAN1_SCE -// CAN2_TX, CAN2_RX0, CAN2_SCE -// CAN3_TX, CAN3_RX0, CAN3_SCE - -typedef struct { - uint32_t w_ptr; - uint32_t r_ptr; - uint32_t fifo_size; - CAN_FIFOMailBox_TypeDef *elems; -} can_ring; - -#define CAN_BUS_RET_FLAG 0x80 -#define CAN_BUS_NUM_MASK 0x7F - -#ifdef PANDA - #define BUS_MAX 4 -#else - #define BUS_MAX 2 -#endif - -extern int can_live, pending_can_live; - -// must reinit after changing these -extern int can_loopback, can_silent; -extern uint32_t can_speed[]; - -void can_set_forwarding(int from, int to); - -void can_init(uint8_t can_number); -void can_init_all(); -void can_send(CAN_FIFOMailBox_TypeDef *to_push, uint8_t bus_number); -int can_pop(can_ring *q, CAN_FIFOMailBox_TypeDef *elem); - -#endif - diff --git a/panda/board/drivers/gmlan_alt.h b/panda/board/drivers/gmlan_alt.h index 8521100a8..d24833a8f 100644 --- a/panda/board/drivers/gmlan_alt.h +++ b/panda/board/drivers/gmlan_alt.h @@ -114,8 +114,6 @@ int get_bit_message(char *out, CAN_FIFOMailBox_TypeDef *to_bang) { return len; } -#ifdef PANDA - void setup_timer4() { // setup TIM4->PSC = 48-1; // tick on 1 us @@ -273,4 +271,3 @@ void bitbang_gmlan(CAN_FIFOMailBox_TypeDef *to_bang) { setup_timer4(); } -#endif diff --git a/panda/board/drivers/llcan.h b/panda/board/drivers/llcan.h new file mode 100644 index 000000000..5c771f76f --- /dev/null +++ b/panda/board/drivers/llcan.h @@ -0,0 +1,80 @@ +// this is needed for 1 mbps support +#define CAN_QUANTA 8 +#define CAN_SEQ1 6 // roundf(quanta * 0.875f) - 1; +#define CAN_SEQ2 1 // roundf(quanta * 0.125f); + +#define CAN_PCLK 24000 +// 333 = 33.3 kbps +// 5000 = 500 kbps +#define can_speed_to_prescaler(x) (CAN_PCLK / CAN_QUANTA * 10 / (x)) + +bool llcan_set_speed(CAN_TypeDef *CAN, uint32_t speed, bool loopback, bool silent) { + // initialization mode + CAN->MCR = CAN_MCR_TTCM | CAN_MCR_INRQ; + while((CAN->MSR & CAN_MSR_INAK) != CAN_MSR_INAK); + + // set time quanta from defines + CAN->BTR = (CAN_BTR_TS1_0 * (CAN_SEQ1-1)) | + (CAN_BTR_TS2_0 * (CAN_SEQ2-1)) | + (can_speed_to_prescaler(speed) - 1); + + // silent loopback mode for debugging + if (loopback) { + CAN->BTR |= CAN_BTR_SILM | CAN_BTR_LBKM; + } + if (silent) { + CAN->BTR |= CAN_BTR_SILM; + } + + // reset + CAN->MCR = CAN_MCR_TTCM | CAN_MCR_ABOM; + + #define CAN_TIMEOUT 1000000 + int tmp = 0; + while((CAN->MSR & CAN_MSR_INAK) == CAN_MSR_INAK && tmp < CAN_TIMEOUT) tmp++; + if (tmp < CAN_TIMEOUT) { + return true; + } + + return false; +} + +void llcan_init(CAN_TypeDef *CAN) { + // accept all filter + CAN->FMR |= CAN_FMR_FINIT; + + // no mask + CAN->sFilterRegister[0].FR1 = 0; + CAN->sFilterRegister[0].FR2 = 0; + CAN->sFilterRegister[14].FR1 = 0; + CAN->sFilterRegister[14].FR2 = 0; + CAN->FA1R |= 1 | (1 << 14); + + CAN->FMR &= ~(CAN_FMR_FINIT); + + // enable certain CAN interrupts + CAN->IER |= CAN_IER_TMEIE | CAN_IER_FMPIE0 | CAN_IER_WKUIE; + + if (CAN == CAN1) { + NVIC_EnableIRQ(CAN1_TX_IRQn); + NVIC_EnableIRQ(CAN1_RX0_IRQn); + NVIC_EnableIRQ(CAN1_SCE_IRQn); + } else if (CAN == CAN2) { + NVIC_EnableIRQ(CAN2_TX_IRQn); + NVIC_EnableIRQ(CAN2_RX0_IRQn); + NVIC_EnableIRQ(CAN2_SCE_IRQn); +#ifdef CAN3 + } else if (CAN == CAN3) { + NVIC_EnableIRQ(CAN3_TX_IRQn); + NVIC_EnableIRQ(CAN3_RX0_IRQn); + NVIC_EnableIRQ(CAN3_SCE_IRQn); +#endif + } +} + +void llcan_clear_send(CAN_TypeDef *CAN) { + CAN->TSR |= CAN_TSR_ABRQ0; + CAN->MSR &= ~(CAN_MSR_ERRI); + CAN->MSR = CAN->MSR; +} + diff --git a/panda/board/drivers/llgpio.h b/panda/board/drivers/llgpio.h index e1835ec0f..984127631 100644 --- a/panda/board/drivers/llgpio.h +++ b/panda/board/drivers/llgpio.h @@ -1,3 +1,12 @@ +#define MODE_INPUT 0 +#define MODE_OUTPUT 1 +#define MODE_ALTERNATE 2 +#define MODE_ANALOG 3 + +#define PULL_NONE 0 +#define PULL_UP 1 +#define PULL_DOWN 2 + void set_gpio_mode(GPIO_TypeDef *GPIO, int pin, int mode) { uint32_t tmp = GPIO->MODER; tmp &= ~(3 << (pin*2)); diff --git a/panda/board/drivers/lline_relay.h b/panda/board/drivers/lline_relay.h deleted file mode 100644 index 217e7dfe3..000000000 --- a/panda/board/drivers/lline_relay.h +++ /dev/null @@ -1,88 +0,0 @@ -#ifdef PANDA - -int relay_control = 0; // True if relay is controlled through l-line - -/* Conrol a relay connected to l-line pin */ - -// 160us cycles, 1 high, 25 low - -volatile int turn_on_relay = 0; -volatile int on_cycles = 25; - -//5s timeout -#define LLINE_TIMEOUT_CYCLES 31250 -volatile int timeout_cycles = LLINE_TIMEOUT_CYCLES; - -void TIM5_IRQHandler(void) { - if (TIM5->SR & TIM_SR_UIF) { - on_cycles--; - timeout_cycles--; - if (timeout_cycles == 0) { - turn_on_relay = 0; - } - if (on_cycles > 0) { - if (turn_on_relay) { - set_gpio_output(GPIOC, 10, 0); - } - } - else { - set_gpio_output(GPIOC, 10, 1); - on_cycles = 25; - } - } - TIM5->ARR = 160-1; - TIM5->SR = 0; -} - -void lline_relay_init (void) { - set_lline_output(0); - relay_control = 1; - set_gpio_output(GPIOC, 10, 1); - - // setup - TIM5->PSC = 48-1; // tick on 1 us - TIM5->CR1 = TIM_CR1_CEN; // enable - TIM5->ARR = 50-1; // 50 us - TIM5->DIER = TIM_DIER_UIE; // update interrupt - TIM5->CNT = 0; - - NVIC_EnableIRQ(TIM5_IRQn); - -#ifdef DEBUG - puts("INIT LLINE\n"); - puts(" SR "); - putui(TIM5->SR); - puts(" PSC "); - putui(TIM5->PSC); - puts(" CR1 "); - putui(TIM5->CR1); - puts(" ARR "); - putui(TIM5->ARR); - puts(" DIER "); - putui(TIM5->DIER); - puts(" SR "); - putui(TIM5->SR); - puts(" CNT "); - putui(TIM5->CNT); - puts("\n"); -#endif -} - -void lline_relay_release (void) { - set_lline_output(0); - relay_control = 0; - puts("RELEASE LLINE\n"); - set_gpio_alternate(GPIOC, 10, GPIO_AF7_USART3); - NVIC_DisableIRQ(TIM5_IRQn); -} - -void set_lline_output(int to_set) { - timeout_cycles = LLINE_TIMEOUT_CYCLES; - turn_on_relay = to_set; -} - -int get_lline_status() { - return turn_on_relay; -} - -#endif diff --git a/panda/board/drivers/spi.h b/panda/board/drivers/spi.h index 7a5945d37..f31f20590 100644 --- a/panda/board/drivers/spi.h +++ b/panda/board/drivers/spi.h @@ -1,5 +1,10 @@ // IRQs: DMA2_Stream2, DMA2_Stream3, EXTI4 +void spi_init(); +int spi_cb_rx(uint8_t *data, int len, uint8_t *data_out); + +// end API + #define SPI_BUF_SIZE 256 uint8_t spi_buf[SPI_BUF_SIZE]; int spi_buf_count = 0; @@ -23,8 +28,8 @@ void spi_init() { // setup interrupt on falling edge of SPI enable (on PA4) SYSCFG->EXTICR[2] = SYSCFG_EXTICR2_EXTI4_PA; - EXTI->IMR = (1 << 4); - EXTI->FTSR = (1 << 4); + EXTI->IMR |= (1 << 4); + EXTI->FTSR |= (1 << 4); NVIC_EnableIRQ(EXTI4_IRQn); } @@ -108,7 +113,7 @@ void DMA2_Stream3_IRQHandler(void) { } void EXTI4_IRQHandler(void) { - volatile int pr = EXTI->PR; + volatile int pr = EXTI->PR & (1 << 4); #ifdef DEBUG_SPI puts("exti4\n"); #endif diff --git a/panda/board/drivers/uart.h b/panda/board/drivers/uart.h index 5ca82888d..baba42e34 100644 --- a/panda/board/drivers/uart.h +++ b/panda/board/drivers/uart.h @@ -1,5 +1,27 @@ // IRQs: USART1, USART2, USART3, UART5 +#define FIFO_SIZE 0x400 +typedef struct uart_ring { + uint16_t w_ptr_tx; + uint16_t r_ptr_tx; + uint8_t elems_tx[FIFO_SIZE]; + uint16_t w_ptr_rx; + uint16_t r_ptr_rx; + uint8_t elems_rx[FIFO_SIZE]; + USART_TypeDef *uart; + void (*callback)(struct uart_ring*); +} uart_ring; + +void uart_init(USART_TypeDef *u, int baud); + +int getc(uart_ring *q, char *elem); +int putc(uart_ring *q, char elem); + +int puts(const char *a); +void puth(unsigned int i); +void hexdump(const void *a, int l); + + // ***************************** serial port queues ***************************** // esp = USART1 diff --git a/panda/board/drivers/usb.h b/panda/board/drivers/usb.h index f2cffa141..606c8c6b8 100644 --- a/panda/board/drivers/usb.h +++ b/panda/board/drivers/usb.h @@ -1,5 +1,35 @@ // IRQs: OTG_FS +typedef union { + uint16_t w; + struct BW { + uint8_t msb; + uint8_t lsb; + } + bw; +} +uint16_t_uint8_t; + +typedef union _USB_Setup { + uint32_t d8[2]; + struct _SetupPkt_Struc + { + uint8_t bmRequestType; + uint8_t bRequest; + uint16_t_uint8_t wValue; + uint16_t_uint8_t wIndex; + uint16_t_uint8_t wLength; + } b; +} +USB_Setup_TypeDef; + +void usb_init(); +int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired); +int usb_cb_ep1_in(uint8_t *usbdata, int len, int hardwired); +void usb_cb_ep2_out(uint8_t *usbdata, int len, int hardwired); +void usb_cb_ep3_out(uint8_t *usbdata, int len, int hardwired); +void usb_cb_enumeration_complete(); + // **** supporting defines **** typedef struct @@ -186,17 +216,10 @@ uint16_t string_manufacturer_desc[] = { 'c', 'o', 'm', 'm', 'a', '.', 'a', 'i' }; -#ifdef PANDA uint16_t string_product_desc[] = { STRING_DESCRIPTOR_HEADER(5), 'p', 'a', 'n', 'd', 'a' }; -#else -uint16_t string_product_desc[] = { - STRING_DESCRIPTOR_HEADER(5), - 'N', 'E', 'O', 'v', '1' -}; -#endif // default serial number when we're not a panda uint16_t string_serial_desc[] = { @@ -210,7 +233,6 @@ uint16_t string_configuration_desc[] = { '0', '1' // "01" }; -#ifdef PANDA // WCID (auto install WinUSB driver) // https://github.com/pbatard/libwdi/wiki/WCID-Devices // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/winusb-installation#automatic-installation-of--winusb-without-an-inf-file @@ -360,8 +382,6 @@ uint8_t winusb_20_desc[WINUSB_PLATFORM_DESCRIPTOR_LENGTH] = { '1', 0x00, 'a', 0x00, 'd', 0x00, 'e', 0x00, '9', 0x00, '}', 0x00, 0x00, 0x00 // 78 bytes }; -#endif - // current packet USB_Setup_TypeDef setup; uint8_t usbdata[0x100]; @@ -550,7 +570,7 @@ void usb_setup() { USB_WritePacket((uint8_t*)string_product_desc, min(sizeof(string_product_desc), setup.b.wLength.w), 0); break; case STRING_OFFSET_ISERIAL: - #ifdef PANDA + #ifdef UID_BASE resp[0] = 0x02 + 12*4; resp[1] = 0x03; @@ -568,14 +588,12 @@ void usb_setup() { USB_WritePacket((const uint8_t *)string_serial_desc, min(sizeof(string_serial_desc), setup.b.wLength.w), 0); #endif break; - #ifdef PANDA case STRING_OFFSET_ICONFIGURATION: USB_WritePacket((uint8_t*)string_configuration_desc, min(sizeof(string_configuration_desc), setup.b.wLength.w), 0); break; case 238: USB_WritePacket((uint8_t*)string_238_desc, min(sizeof(string_238_desc), setup.b.wLength.w), 0); break; - #endif default: // nothing USB_WritePacket(0, 0, 0); @@ -583,12 +601,10 @@ void usb_setup() { } USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; break; - #ifdef PANDA case USB_DESC_TYPE_BINARY_OBJECT_STORE: USB_WritePacket(binary_object_store_desc, min(sizeof(binary_object_store_desc), setup.b.wLength.w), 0); USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; break; - #endif default: // nothing here? USB_WritePacket(0, 0, 0); @@ -609,7 +625,6 @@ void usb_setup() { USB_WritePacket(0, 0, 0); USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; break; - #ifdef PANDA case WEBUSB_VENDOR_CODE: switch (setup.b.wIndex.w) { case WEBUSB_REQ_GET_URL: @@ -641,7 +656,6 @@ void usb_setup() { USB_WritePacket_EP0(0, 0); } break; - #endif default: resp_len = usb_cb_control_msg(&setup, resp, 1); USB_WritePacket(resp, min(resp_len, setup.b.wLength.w), 0); diff --git a/panda/board/gpio.h b/panda/board/gpio.h index ede6c9b3e..7ba0dff58 100644 --- a/panda/board/gpio.h +++ b/panda/board/gpio.h @@ -1,3 +1,5 @@ +// this is last place with ifdef PANDA + #ifdef STM32F4 #include "stm32f4xx_hal_gpio_ex.h" #else @@ -61,43 +63,6 @@ void detect() { // ********************* bringup ********************* -void clock_init() { - // enable external oscillator - RCC->CR |= RCC_CR_HSEON; - while ((RCC->CR & RCC_CR_HSERDY) == 0); - - // divide shit - RCC->CFGR = RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PPRE2_DIV2 | RCC_CFGR_PPRE1_DIV4; - #ifdef PANDA - RCC->PLLCFGR = RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLM_3 | - RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_5 | RCC_PLLCFGR_PLLSRC_HSE; - #else - #ifdef PEDAL - // comma pedal has a 16mhz crystal - RCC->PLLCFGR = RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLM_3 | - RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_5 | RCC_PLLCFGR_PLLSRC_HSE; - #else - // NEO board has a 8mhz crystal - RCC->PLLCFGR = RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLM_3 | - RCC_PLLCFGR_PLLN_7 | RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLSRC_HSE; - #endif - #endif - - // start PLL - RCC->CR |= RCC_CR_PLLON; - while ((RCC->CR & RCC_CR_PLLRDY) == 0); - - // Configure Flash prefetch, Instruction cache, Data cache and wait state - // *** without this, it breaks *** - FLASH->ACR = FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_LATENCY_5WS; - - // switch to PLL - RCC->CFGR |= RCC_CFGR_SW_PLL; - while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL); - - // *** running on PLL *** -} - void periph_init() { // enable GPIOB, UART2, CAN, USB clock RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; @@ -117,18 +82,16 @@ void periph_init() { RCC->APB1ENR |= RCC_APB1ENR_CAN3EN; #endif RCC->APB1ENR |= RCC_APB1ENR_DACEN; - RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; - RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; - RCC->APB1ENR |= RCC_APB1ENR_TIM4EN; - RCC->APB1ENR |= RCC_APB1ENR_TIM5EN; - RCC->APB1ENR |= RCC_APB1ENR_TIM6EN; + RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // main counter + RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; // slow loop and pedal + RCC->APB1ENR |= RCC_APB1ENR_TIM4EN; // gmlan_alt + //RCC->APB1ENR |= RCC_APB1ENR_TIM5EN; + //RCC->APB1ENR |= RCC_APB1ENR_TIM6EN; RCC->APB2ENR |= RCC_APB2ENR_USART1EN; RCC->AHB2ENR |= RCC_AHB2ENR_OTGFSEN; - RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; + //RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; RCC->APB2ENR |= RCC_APB2ENR_SPI1EN; - - // needed? RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; } @@ -197,7 +160,7 @@ void set_can_mode(int can, int use_gmlan) { set_gpio_alternate(GPIOB, 12, GPIO_AF9_CAN2); set_gpio_alternate(GPIOB, 13, GPIO_AF9_CAN2); #ifdef CAN3 - } else if (revision == PANDA_REV_C && can == 2) { + } else if (can == 2) { // A8,A15: disable normal mode set_gpio_mode(GPIOA, 8, MODE_INPUT); set_gpio_mode(GPIOA, 15, MODE_INPUT); @@ -218,11 +181,9 @@ void set_can_mode(int can, int use_gmlan) { set_gpio_alternate(GPIOB, 6, GPIO_AF9_CAN2); #ifdef CAN3 } else if (can == 2) { - if(revision == PANDA_REV_C){ - // B3,B4: disable gmlan mode - set_gpio_mode(GPIOB, 3, MODE_INPUT); - set_gpio_mode(GPIOB, 4, MODE_INPUT); - } + // B3,B4: disable gmlan mode + set_gpio_mode(GPIOB, 3, MODE_INPUT); + set_gpio_mode(GPIOB, 4, MODE_INPUT); // A8,A15: normal mode set_gpio_alternate(GPIOA, 8, GPIO_AF11_CAN3); set_gpio_alternate(GPIOA, 15, GPIO_AF11_CAN3); @@ -377,11 +338,7 @@ void gpio_init() { #ifdef PANDA // K-line enable moved from B4->B7 to make room for GMLAN on CAN3 - if (revision == PANDA_REV_C) { - set_gpio_output(GPIOB, 7, 1); // REV C - } else { - set_gpio_output(GPIOB, 4, 1); // REV AB - } + set_gpio_output(GPIOB, 7, 1); // REV C // C12,D2: K-Line setup on UART 5 set_gpio_alternate(GPIOC, 12, GPIO_AF8_UART5); @@ -392,16 +349,12 @@ void gpio_init() { set_gpio_output(GPIOA, 14, 1); // C10,C11: L-Line setup on USART 3 - // LLine now used for relay output - set_gpio_output(GPIOC, 10, 1); - //set_gpio_alternate(GPIOC, 10, GPIO_AF7_USART3); + set_gpio_alternate(GPIOC, 10, GPIO_AF7_USART3); set_gpio_alternate(GPIOC, 11, GPIO_AF7_USART3); set_gpio_pullup(GPIOC, 11, PULL_UP); #endif - if (revision == PANDA_REV_C) { - set_usb_power_mode(USB_POWER_CLIENT); - } + set_usb_power_mode(USB_POWER_CLIENT); } // ********************* early bringup ********************* diff --git a/panda/board/main.c b/panda/board/main.c index 4fb5e9ff0..c80a3b9ba 100644 --- a/panda/board/main.c +++ b/panda/board/main.c @@ -1,14 +1,15 @@ +//#define EON + #include "config.h" #include "obj/gitversion.h" // ********************* includes ********************* + #include "libc.h" -#include "safety.h" #include "provision.h" -#include "drivers/drivers.h" - +#include "drivers/llcan.h" #include "drivers/llgpio.h" #include "gpio.h" @@ -16,25 +17,13 @@ #include "drivers/adc.h" #include "drivers/usb.h" #include "drivers/gmlan_alt.h" -#include "drivers/can.h" #include "drivers/spi.h" #include "drivers/timer.h" +#include "drivers/clock.h" #include "power_saving.h" - - -// ***************************** fan ***************************** - -void fan_init() { - // timer for fan PWM - TIM3->CCMR2 = TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1; - TIM3->CCER = TIM_CCER_CC3E; - timer_init(TIM3, 10); -} - -void fan_set_speed(int fan_speed) { - TIM3->CCR3 = fan_speed; -} +#include "safety.h" +#include "drivers/can.h" // ********************* serial debugging ********************* @@ -70,6 +59,41 @@ void debug_ring_callback(uart_ring *ring) { } } +// ***************************** started logic ***************************** + +int is_gpio_started() { + // ignition is on PA1 + return (GPIOA->IDR & (1 << 1)) == 0; +} + +void EXTI1_IRQHandler() { + volatile int pr = EXTI->PR & (1 << 1); + if (pr & (1 << 1)) { + #ifdef DEBUG + puts("got started interrupt\n"); + #endif + + // jenky debounce + delay(100000); + + // set power savings mode here + if (is_gpio_started() == 1) { + power_save_disable(); + } else { + power_save_enable(); + } + EXTI->PR = (1 << 1); + } +} + +void started_interrupt_init() { + SYSCFG->EXTICR[1] = SYSCFG_EXTICR1_EXTI1_PA; + EXTI->IMR |= (1 << 1); + EXTI->RTSR |= (1 << 1); + EXTI->FTSR |= (1 << 1); + NVIC_EnableIRQ(EXTI1_IRQn); +} + // ***************************** USB port ***************************** int get_health_pkt(void *dat) { @@ -85,40 +109,25 @@ int get_health_pkt(void *dat) { //Voltage will be measured in mv. 5000 = 5V uint32_t voltage = adc_get(ADCCHAN_VOLTAGE); - if (revision == PANDA_REV_AB) { - //REVB has a 100, 27 (27/127) voltage divider - //Here is the calculation for the scale - //ADCV = VIN_S * (27/127) * (4095/3.3) - //RETVAL = ADCV * s = VIN_S*1000 - //s = 1000/((4095/3.3)*(27/127)) = 3.79053046 - //Avoid needing floating point math - health->voltage = (voltage * 3791) / 1000; - } else { - //REVC has a 10, 1 (1/11) voltage divider - //Here is the calculation for the scale (s) - //ADCV = VIN_S * (1/11) * (4095/3.3) - //RETVAL = ADCV * s = VIN_S*1000 - //s = 1000/((4095/3.3)*(1/11)) = 8.8623046875 + // REVC has a 10, 1 (1/11) voltage divider + // Here is the calculation for the scale (s) + // ADCV = VIN_S * (1/11) * (4095/3.3) + // RETVAL = ADCV * s = VIN_S*1000 + // s = 1000/((4095/3.3)*(1/11)) = 8.8623046875 - //Avoid needing floating point math - health->voltage = (voltage * 8862) / 1000; - } + // Avoid needing floating point math + health->voltage = (voltage * 8862) / 1000; -#ifdef PANDA health->current = adc_get(ADCCHAN_CURRENT); int safety_ignition = safety_ignition_hook(); if (safety_ignition < 0) { //Use the GPIO pin to determine ignition - health->started = (GPIOA->IDR & (1 << 1)) == 0; + health->started = is_gpio_started(); } else { //Current safety hooks want to determine ignition (ex: GM) health->started = safety_ignition; } -#else - health->current = 0; - health->started = (GPIOC->IDR & (1 << 13)) != 0; -#endif health->controls_allowed = controls_allowed; health->gas_interceptor_detected = gas_interceptor_detected; @@ -143,7 +152,6 @@ void usb_cb_ep2_out(uint8_t *usbdata, int len, int hardwired) { uart_ring *ur = get_ring_by_number(usbdata[0]); if (!ur) return; if ((usbdata[0] < 2) || safety_tx_lin_hook(usbdata[0]-2, usbdata+1, len-1)) { - if (ur == &esp_ring) power_save_reset_timer(); for (int i = 1; i < len; i++) while (!putc(ur, usbdata[i])); } } @@ -163,14 +171,6 @@ void usb_cb_ep3_out(uint8_t *usbdata, int len, int hardwired) { uint8_t bus_number = (to_push.RDTR >> 4) & CAN_BUS_NUM_MASK; can_send(&to_push, bus_number); - - #ifdef PANDA - // Enable relay on can message if allowed. - // Temporary until OP has support for relay - if (safety_relay_hook()) { - set_lline_output(1); - } - #endif } } @@ -201,16 +201,14 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) { break; // **** 0xd0: fetch serial number case 0xd0: - #ifdef PANDA - // addresses are OTP - if (setup->b.wValue.w == 1) { - memcpy(resp, (void *)0x1fff79c0, 0x10); - resp_len = 0x10; - } else { - get_provision_chunk(resp); - resp_len = PROVISION_CHUNK_LEN; - } - #endif + // addresses are OTP + if (setup->b.wValue.w == 1) { + memcpy(resp, (void *)0x1fff79c0, 0x10); + resp_len = 0x10; + } else { + get_provision_chunk(resp); + resp_len = PROVISION_CHUNK_LEN; + } break; // **** 0xd1: enter bootloader mode case 0xd1: @@ -235,10 +233,6 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) { case 0xd2: resp_len = get_health_pkt(resp); break; - // **** 0xd3: set fan speed - case 0xd3: - fan_set_speed(setup->b.wValue.w); - break; // **** 0xd6: get version case 0xd6: COMPILE_TIME_ASSERT(sizeof(gitversion) <= MAX_RESP_LEN) @@ -273,44 +267,43 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) { break; // **** 0xdb: set GMLAN multiplexing mode case 0xdb: - #ifdef PANDA - if (setup->b.wValue.w == 1) { - // GMLAN ON - if (setup->b.wIndex.w == 1) { - can_set_gmlan(1); - } else if (setup->b.wIndex.w == 2) { - // might be ignored on rev b panda - can_set_gmlan(2); - } - } else { - can_set_gmlan(-1); + if (setup->b.wValue.w == 1) { + // GMLAN ON + if (setup->b.wIndex.w == 1) { + can_set_gmlan(1); + } else if (setup->b.wIndex.w == 2) { + can_set_gmlan(2); } - #endif + } else { + can_set_gmlan(-1); + } break; // **** 0xdc: set safety mode case 0xdc: // this is the only way to leave silent mode // and it's blocked over WiFi // Allow ELM security mode to be set over wifi. - if (hardwired || setup->b.wValue.w == SAFETY_NOOUTPUT || setup->b.wValue.w == SAFETY_ELM327) { + if (hardwired || (setup->b.wValue.w == SAFETY_NOOUTPUT) || (setup->b.wValue.w == SAFETY_ELM327)) { safety_set_mode(setup->b.wValue.w, (int16_t)setup->b.wIndex.w); - switch (setup->b.wValue.w) { - case SAFETY_NOOUTPUT: - can_silent = ALL_CAN_SILENT; - break; - case SAFETY_ELM327: - can_silent = ALL_CAN_BUT_MAIN_SILENT; - can_autobaud_enabled[0] = false; - break; - default: - can_silent = ALL_CAN_LIVE; - can_autobaud_enabled[0] = false; - can_autobaud_enabled[1] = false; - #ifdef PANDA - can_autobaud_enabled[2] = false; - #endif - break; + if (safety_ignition_hook() != -1) { + // if the ignition hook depends on something other than the started GPIO + // we have to disable power savings (fix for GM and Tesla) + power_save_disable(); } + #ifndef EON + // always LIVE on EON + switch (setup->b.wValue.w) { + case SAFETY_NOOUTPUT: + can_silent = ALL_CAN_SILENT; + break; + case SAFETY_ELM327: + can_silent = ALL_CAN_BUT_MAIN_SILENT; + break; + default: + can_silent = ALL_CAN_LIVE; + break; + } + #endif can_init_all(); } break; @@ -318,21 +311,26 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) { case 0xdd: // wValue = Can Bus Num to forward from // wIndex = Can Bus Num to forward to - if (setup->b.wValue.w < BUS_MAX && setup->b.wIndex.w < BUS_MAX && - setup->b.wValue.w != setup->b.wIndex.w) { // set forwarding + if ((setup->b.wValue.w < BUS_MAX) && (setup->b.wIndex.w < BUS_MAX) && + (setup->b.wValue.w != setup->b.wIndex.w)) { // set forwarding can_set_forwarding(setup->b.wValue.w, setup->b.wIndex.w & CAN_BUS_NUM_MASK); - } else if(setup->b.wValue.w < BUS_MAX && setup->b.wIndex.w == 0xFF){ //Clear Forwarding + } else if((setup->b.wValue.w < BUS_MAX) && (setup->b.wIndex.w == 0xFF)){ //Clear Forwarding can_set_forwarding(setup->b.wValue.w, -1); } break; // **** 0xde: set can bitrate case 0xde: if (setup->b.wValue.w < BUS_MAX) { - can_autobaud_enabled[setup->b.wValue.w] = false; can_speed[setup->b.wValue.w] = setup->b.wIndex.w; can_init(CAN_NUM_FROM_BUS_NUM(setup->b.wValue.w)); } break; + // **** 0xdf: set long controls allowed + case 0xdf: + if (hardwired) { + long_controls_allowed = setup->b.wValue.w & 1; + } + break; // **** 0xe0: uart read case 0xe0: ur = get_ring_by_number(setup->b.wValue.w); @@ -386,17 +384,15 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) { break; // **** 0xe6: set USB power case 0xe6: - if (revision == PANDA_REV_C) { - if (setup->b.wValue.w == 1) { - puts("user setting CDP mode\n"); - set_usb_power_mode(USB_POWER_CDP); - } else if (setup->b.wValue.w == 2) { - puts("user setting DCP mode\n"); - set_usb_power_mode(USB_POWER_DCP); - } else { - puts("user setting CLIENT mode\n"); - set_usb_power_mode(USB_POWER_CLIENT); - } + if (setup->b.wValue.w == 1) { + puts("user setting CDP mode\n"); + set_usb_power_mode(USB_POWER_CDP); + } else if (setup->b.wValue.w == 2) { + puts("user setting DCP mode\n"); + set_usb_power_mode(USB_POWER_DCP); + } else { + puts("user setting CLIENT mode\n"); + set_usb_power_mode(USB_POWER_CLIENT); } break; // **** 0xf0: do k-line wValue pulse on uart2 for Acura @@ -452,16 +448,6 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) { } break; } - // **** 0xf3: set l-line relay - case 0xf3: - { - #ifdef PANDA - if (safety_relay_hook()) { - set_lline_output(setup->b.wValue.w == 1); - } - #endif - break; - } default: puts("NO HANDLER "); puth(setup->b.bRequest); @@ -471,7 +457,6 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) { return resp_len; } -#ifdef PANDA int spi_cb_rx(uint8_t *data, int len, uint8_t *data_out) { // data[0] = endpoint // data[2] = length @@ -499,12 +484,6 @@ int spi_cb_rx(uint8_t *data, int len, uint8_t *data_out) { return resp_len; } -#else - -int spi_cb_rx(uint8_t *data, int len, uint8_t *data_out) { return 0; }; - -#endif - // ***************************** main code ***************************** @@ -514,7 +493,99 @@ void __initialize_hardware_early() { void __attribute__ ((noinline)) enable_fpu() { // enable the FPU - SCB->CPACR |= ((3UL << 10*2) | (3UL << 11*2)); + SCB->CPACR |= ((3UL << (10 * 2)) | (3UL << (11 * 2))); +} + +uint64_t tcnt = 0; +uint64_t marker = 0; + +// called once per second +void TIM3_IRQHandler() { + #define CURRENT_THRESHOLD 0xF00 + #define CLICKS 5 // 5 seconds to switch modes + + if (TIM3->SR != 0) { + can_live = pending_can_live; + + //puth(usart1_dma); puts(" "); puth(DMA2_Stream5->M0AR); puts(" "); puth(DMA2_Stream5->NDTR); puts("\n"); + + uint32_t current = adc_get(ADCCHAN_CURRENT); + + switch (usb_power_mode) { + case USB_POWER_CLIENT: + if ((tcnt-marker) >= CLICKS) { + if (!is_enumerated) { + puts("USBP: didn't enumerate, switching to CDP mode\n"); + // switch to CDP + set_usb_power_mode(USB_POWER_CDP); + marker = tcnt; + } + } + // keep resetting the timer if it's enumerated + if (is_enumerated) { + marker = tcnt; + } + break; + case USB_POWER_CDP: + // On the EON, if we get into CDP mode we stay here. No need to go to DCP. + #ifndef EON + // been CLICKS clicks since we switched to CDP + if ((tcnt-marker) >= CLICKS) { + // measure current draw, if positive and no enumeration, switch to DCP + if (!is_enumerated && (current < CURRENT_THRESHOLD)) { + puts("USBP: no enumeration with current draw, switching to DCP mode\n"); + set_usb_power_mode(USB_POWER_DCP); + marker = tcnt; + } + } + // keep resetting the timer if there's no current draw in CDP + if (current >= CURRENT_THRESHOLD) { + marker = tcnt; + } + #endif + break; + case USB_POWER_DCP: + // been at least CLICKS clicks since we switched to DCP + if ((tcnt-marker) >= CLICKS) { + // if no current draw, switch back to CDP + if (current >= CURRENT_THRESHOLD) { + puts("USBP: no current draw, switching back to CDP mode\n"); + set_usb_power_mode(USB_POWER_CDP); + marker = tcnt; + } + } + // keep resetting the timer if there's current draw in DCP + if (current < CURRENT_THRESHOLD) { + marker = tcnt; + } + break; + } + + // ~0x9a = 500 ma + /*puth(current); + puts("\n");*/ + + // reset this every 16th pass + if ((tcnt&0xF) == 0) pending_can_live = 0; + + #ifdef DEBUG + puts("** blink "); + puth(can_rx_q.r_ptr); puts(" "); puth(can_rx_q.w_ptr); puts(" "); + puth(can_tx1_q.r_ptr); puts(" "); puth(can_tx1_q.w_ptr); puts(" "); + puth(can_tx2_q.r_ptr); puts(" "); puth(can_tx2_q.w_ptr); puts("\n"); + #endif + + // set green LED to be controls allowed + set_led(LED_GREEN, controls_allowed); + + // turn off the blue LED, turned on by CAN + // unless we are in power saving mode + set_led(LED_BLUE, (tcnt&1) && power_save_status == POWER_SAVE_STATUS_ENABLED); + + // on to the next one + tcnt += 1; + } + TIM3->SR = 0; } int main() { @@ -531,21 +602,19 @@ int main() { // detect the revision and init the GPIOs puts("config:\n"); - #ifdef PANDA - puts(revision == PANDA_REV_C ? " panda rev c\n" : " panda rev a or b\n"); - #else - puts(" legacy\n"); - #endif + puts((revision == PANDA_REV_C) ? " panda rev c\n" : " panda rev a or b\n"); puts(has_external_debug_serial ? " real serial\n" : " USB serial\n"); puts(is_giant_panda ? " GIANTpanda detected\n" : " not GIANTpanda\n"); puts(is_grey_panda ? " gray panda detected!\n" : " white panda\n"); puts(is_entering_bootmode ? " ESP wants bootmode\n" : " no bootmode\n"); + + // non rev c panda are no longer supported + while (revision != PANDA_REV_C); + gpio_init(); -#ifdef PANDA // panda has an FPU, let's use it! enable_fpu(); -#endif // enable main uart if it's connected if (has_external_debug_serial) { @@ -554,22 +623,18 @@ int main() { uart_init(USART2, 115200); } -#ifdef PANDA if (is_grey_panda) { uart_init(USART1, 9600); } else { // enable ESP uart uart_init(USART1, 115200); - #ifdef EON - set_esp_mode(ESP_DISABLED); - #endif } + // enable LIN uart_init(UART5, 10400); UART5->CR2 |= USART_CR2_LINEN; uart_init(USART3, 10400); USART3->CR2 |= USART_CR2_LINEN; -#endif // init microsecond system timer // increments 1000000 times per second @@ -585,136 +650,65 @@ int main() { // default to silent mode to prevent issues with Ford // hardcode a specific safety mode if you want to force the panda to be in a specific mode safety_set_mode(SAFETY_NOOUTPUT, 0); +#ifdef EON + // if we're on an EON, it's fine for CAN to be live for fingerprinting + can_silent = ALL_CAN_LIVE; +#else can_silent = ALL_CAN_SILENT; +#endif can_init_all(); adc_init(); - -#ifdef PANDA spi_init(); + +#ifdef EON + // have to save power + if (!is_grey_panda) { + set_esp_mode(ESP_DISABLED); + } + // only enter power save after the first cycle + /*if (is_gpio_started() == 0) { + power_save_enable(); + }*/ + // interrupt on started line + started_interrupt_init(); #endif + + // 48mhz / 65536 ~= 732 / 732 = 1 + timer_init(TIM3, 732); + NVIC_EnableIRQ(TIM3_IRQn); + #ifdef DEBUG puts("DEBUG ENABLED\n"); #endif - // set PWM - fan_init(); - fan_set_speed(0); - puts("**** INTERRUPTS ON ****\n"); __enable_irq(); - power_save_init(); - - // if the error interrupt is enabled to quickly when the CAN bus is active - // something bad happens and you can't connect to the device over USB - delay(10000000); - CAN1->IER |= CAN_IER_ERRIE | CAN_IER_LECIE; - // LED should keep on blinking all the time uint64_t cnt = 0; - #ifdef PANDA - uint64_t marker = 0; - #define CURRENT_THRESHOLD 0xF00 - #define CLICKS 8 - #endif - for (cnt=0;;cnt++) { - can_live = pending_can_live; + if (power_save_status == POWER_SAVE_STATUS_DISABLED) { + int div_mode = ((usb_power_mode == USB_POWER_DCP) ? 4 : 1); - //puth(usart1_dma); puts(" "); puth(DMA2_Stream5->M0AR); puts(" "); puth(DMA2_Stream5->NDTR); puts("\n"); - - #ifdef PANDA - uint32_t current = adc_get(ADCCHAN_CURRENT); - - switch (usb_power_mode) { - case USB_POWER_CLIENT: - if ((cnt-marker) >= CLICKS) { - if (!is_enumerated) { - puts("USBP: didn't enumerate, switching to CDP mode\n"); - // switch to CDP - set_usb_power_mode(USB_POWER_CDP); - marker = cnt; - } + // useful for debugging, fade breaks = panda is overloaded + for (int div_mode_loop = 0; div_mode_loop < div_mode; div_mode_loop++) { + for (int fade = 0; fade < 1024; fade += 8) { + for (int i = 0; i < (128/div_mode); i++) { + set_led(LED_RED, 1); + if (fade < 512) { delay(fade); } else { delay(1024-fade); } + set_led(LED_RED, 0); + if (fade < 512) { delay(512-fade); } else { delay(fade-512); } } - // keep resetting the timer if it's enumerated - if (is_enumerated) { - marker = cnt; - } - break; - case USB_POWER_CDP: -#ifndef EON - // been CLICKS clicks since we switched to CDP - if ((cnt-marker) >= CLICKS) { - // measure current draw, if positive and no enumeration, switch to DCP - if (!is_enumerated && current < CURRENT_THRESHOLD) { - puts("USBP: no enumeration with current draw, switching to DCP mode\n"); - set_usb_power_mode(USB_POWER_DCP); - marker = cnt; - } - } - // keep resetting the timer if there's no current draw in CDP - if (current >= CURRENT_THRESHOLD) { - marker = cnt; - } -#endif - break; - case USB_POWER_DCP: - // been at least CLICKS clicks since we switched to DCP - if ((cnt-marker) >= CLICKS) { - // if no current draw, switch back to CDP - if (current >= CURRENT_THRESHOLD) { - puts("USBP: no current draw, switching back to CDP mode\n"); - set_usb_power_mode(USB_POWER_CDP); - marker = cnt; - } - } - // keep resetting the timer if there's current draw in DCP - if (current < CURRENT_THRESHOLD) { - marker = cnt; - } - break; - } - - // ~0x9a = 500 ma - /*puth(current); - puts("\n");*/ - #endif - - // reset this every 16th pass - if ((cnt&0xF) == 0) pending_can_live = 0; - - #ifdef DEBUG - puts("** blink "); - puth(can_rx_q.r_ptr); puts(" "); puth(can_rx_q.w_ptr); puts(" "); - puth(can_tx1_q.r_ptr); puts(" "); puth(can_tx1_q.w_ptr); puts(" "); - puth(can_tx2_q.r_ptr); puts(" "); puth(can_tx2_q.w_ptr); puts("\n"); - #endif - - // set green LED to be controls allowed - set_led(LED_GREEN, controls_allowed); - - // blink the red LED - int div_mode = ((usb_power_mode == USB_POWER_DCP) ? 4 : 1); - - for (int div_mode_loop = 0; div_mode_loop < div_mode; div_mode_loop++) { - for (int fade = 0; fade < 1024; fade += 8) { - for (int i = 0; i < 128/div_mode; i++) { - set_led(LED_RED, 0); - if (fade < 512) { delay(512-fade); } else { delay(fade-512); } - set_led(LED_RED, 1); - if (fade < 512) { delay(fade); } else { delay(1024-fade); } } } + } else { + __WFI(); } - - // turn off the blue LED, turned on by CAN - #ifdef PANDA - set_led(LED_BLUE, 0); - #endif } return 0; } + diff --git a/panda/board/pedal/main.c b/panda/board/pedal/main.c index 6b55ca780..df3219e32 100644 --- a/panda/board/pedal/main.c +++ b/panda/board/pedal/main.c @@ -1,29 +1,26 @@ -//#define DEBUG -//#define CAN_LOOPBACK_MODE -//#define USE_INTERNAL_OSC - #include "../config.h" -#include "drivers/drivers.h" +#include "drivers/llcan.h" #include "drivers/llgpio.h" -#include "gpio.h" - -#define CUSTOM_CAN_INTERRUPTS - -#include "libc.h" -#include "safety.h" +#include "drivers/clock.h" #include "drivers/adc.h" -#include "drivers/uart.h" #include "drivers/dac.h" -#include "drivers/can.h" #include "drivers/timer.h" +#include "gpio.h" +#include "libc.h" + #define CAN CAN1 //#define PEDAL_USB #ifdef PEDAL_USB + #include "drivers/uart.h" #include "drivers/usb.h" +#else + // no serial either + int puts(const char *a) { return 0; } + void puth(unsigned int i) {} #endif #define ENTER_BOOTLOADER_MAGIC 0xdeadbeef @@ -35,6 +32,8 @@ void __initialize_hardware_early() { // ********************* serial debugging ********************* +#ifdef PEDAL_USB + void debug_ring_callback(uart_ring *ring) { char rcv; while (getc(ring, &rcv)) { @@ -42,8 +41,6 @@ void debug_ring_callback(uart_ring *ring) { } } -#ifdef PEDAL_USB - int usb_cb_ep1_in(uint8_t *usbdata, int len, int hardwired) { return 0; } void usb_cb_ep2_out(uint8_t *usbdata, int len, int hardwired) {} void usb_cb_ep3_out(uint8_t *usbdata, int len, int hardwired) {} @@ -185,7 +182,7 @@ void CAN1_RX0_IRQHandler() { void CAN1_SCE_IRQHandler() { state = FAULT_SCE; - can_sce(CAN); + llcan_clear_send(CAN); } int pdl0 = 0, pdl1 = 0; @@ -256,8 +253,7 @@ void pedal() { dac_set(1, pdl1); } - // feed the watchdog - IWDG->KR = 0xAAAA; + watchdog_feed(); } int main() { @@ -278,24 +274,18 @@ int main() { adc_init(); // init can - can_silent = ALL_CAN_LIVE; - can_init(0); + llcan_set_speed(CAN1, 5000, false, false); + llcan_init(CAN1); // 48mhz / 65536 ~= 732 timer_init(TIM3, 15); NVIC_EnableIRQ(TIM3_IRQn); - // setup watchdog - IWDG->KR = 0x5555; - IWDG->PR = 0; // divider /4 - // 0 = 0.125 ms, let's have a 50ms watchdog - IWDG->RLR = 400 - 1; - IWDG->KR = 0xCCCC; + watchdog_init(); puts("**** INTERRUPTS ON ****\n"); __enable_irq(); - // main pedal loop while (1) { pedal(); diff --git a/panda/board/power_saving.h b/panda/board/power_saving.h index c6f83457f..3f40bce28 100644 --- a/panda/board/power_saving.h +++ b/panda/board/power_saving.h @@ -1,157 +1,57 @@ #define POWER_SAVE_STATUS_DISABLED 0 -//Moving to enabled, but can wakeup not yet enabled -#define POWER_SAVE_STATUS_SWITCHING 1 -#define POWER_SAVE_STATUS_ENABLED 2 +#define POWER_SAVE_STATUS_ENABLED 1 -volatile int power_save_status = POWER_SAVE_STATUS_DISABLED; +int power_save_status = POWER_SAVE_STATUS_DISABLED; void power_save_enable(void) { - power_save_status = POWER_SAVE_STATUS_SWITCHING; - puts("Saving power\n"); - //Turn off can transciever + if (power_save_status == POWER_SAVE_STATUS_ENABLED) return; + puts("enable power savings\n"); + + // turn off can set_can_enable(CAN1, 0); set_can_enable(CAN2, 0); -#ifdef PANDA set_can_enable(CAN3, 0); -#endif - //Turn off GMLAN + // turn off GMLAN set_gpio_output(GPIOB, 14, 0); set_gpio_output(GPIOB, 15, 0); -#ifdef PANDA - //Turn off LIN K - if (revision == PANDA_REV_C) { - set_gpio_output(GPIOB, 7, 0); // REV C - } else { - set_gpio_output(GPIOB, 4, 0); // REV AB - } - // LIN L + // turn off LIN + set_gpio_output(GPIOB, 7, 0); set_gpio_output(GPIOA, 14, 0); -#endif if (is_grey_panda) { - char* UBLOX_SLEEP_MSG = "\xb5\x62\x06\x04\x04\x00\x01\x00\x08\x00\x17\x78"; - int len = 12; + char UBLOX_SLEEP_MSG[] = "\xb5\x62\x06\x04\x04\x00\x01\x00\x08\x00\x17\x78"; uart_ring *ur = get_ring_by_number(1); - for (int i = 0; i < len; i++) while (!putc(ur, UBLOX_SLEEP_MSG[i])); + for (int i = 0; i < sizeof(UBLOX_SLEEP_MSG)-1; i++) while (!putc(ur, UBLOX_SLEEP_MSG[i])); } - //Setup timer for can enable - TIM6->PSC = 48-1; // tick on 1 us - - TIM6->ARR = 12; // 12us - // Enable, One-Pulse Mode, Only overflow interrupt - TIM6->CR1 = TIM_CR1_CEN | TIM_CR1_OPM | TIM_CR1_URS; - TIM6->EGR = TIM_EGR_UG; - TIM6->CR1 |= TIM_CR1_CEN; -} - -void power_save_enable_can_wake(void) { - // CAN Automatic Wake must be done a little while after the sleep - // On some cars turning off the can transciver can trigger the wakeup power_save_status = POWER_SAVE_STATUS_ENABLED; - puts("Turning can off\n"); - CAN1->MCR |= CAN_MCR_SLEEP; - CAN1->MCR |= CAN_MCR_AWUM; - - CAN2->MCR |= CAN_MCR_SLEEP; - CAN2->MCR |= CAN_MCR_AWUM; -#ifdef PANDA - CAN3->MCR |= CAN_MCR_SLEEP; - CAN3->MCR |= CAN_MCR_AWUM; -#endif - - //set timer back - TIM6->PSC = 48000-1; // tick on 1 ms - TIM6->ARR = 10000; // 10s - // Enable, One-Pulse Mode, Only overflow interrupt - TIM6->CR1 = TIM_CR1_OPM | TIM_CR1_URS; - TIM6->EGR = TIM_EGR_UG; } void power_save_disable(void) { - power_save_status = POWER_SAVE_STATUS_DISABLED; - puts("not Saving power\n"); - TIM6->CR1 |= TIM_CR1_CEN; //Restart timer - TIM6->CNT = 0; + if (power_save_status == POWER_SAVE_STATUS_DISABLED) return; + puts("disable power savings\n"); - //Turn on can + // turn on can set_can_enable(CAN1, 1); set_can_enable(CAN2, 1); - -#ifdef PANDA set_can_enable(CAN3, 1); -#endif - //Turn on GMLAN + // turn on GMLAN set_gpio_output(GPIOB, 14, 1); set_gpio_output(GPIOB, 15, 1); -#ifdef PANDA - //Turn on LIN K - if (revision == PANDA_REV_C) { - set_gpio_output(GPIOB, 7, 1); // REV C - } else { - set_gpio_output(GPIOB, 4, 1); // REV AB - } - // LIN L + // turn on LIN + set_gpio_output(GPIOB, 7, 1); set_gpio_output(GPIOA, 14, 1); -#endif if (is_grey_panda) { - char* UBLOX_WAKE_MSG = "\xb5\x62\x06\x04\x04\x00\x01\x00\x09\x00\x18\x7a"; - int len = 12; + char UBLOX_WAKE_MSG[] = "\xb5\x62\x06\x04\x04\x00\x01\x00\x09\x00\x18\x7a"; uart_ring *ur = get_ring_by_number(1); - for (int i = 0; i < len; i++) while (!putc(ur, UBLOX_WAKE_MSG[i])); + for (int i = 0; i < sizeof(UBLOX_WAKE_MSG)-1; i++) while (!putc(ur, UBLOX_WAKE_MSG[i])); } - //set timer back - TIM6->PSC = 48000-1; // tick on 1 ms - TIM6->ARR = 10000; // 10s - // Enable, One-Pulse Mode, Only overflow interrupt - TIM6->CR1 = TIM_CR1_CEN | TIM_CR1_OPM | TIM_CR1_URS; - TIM6->EGR = TIM_EGR_UG; - TIM6->CR1 |= TIM_CR1_CEN; + power_save_status = POWER_SAVE_STATUS_DISABLED; } - - -// Reset timer when activity -void power_save_reset_timer() { - TIM6->CNT = 0; - if (power_save_status != POWER_SAVE_STATUS_DISABLED){ - power_save_disable(); - } -} - -void power_save_init(void) { - puts("Saving power init\n"); - TIM6->PSC = 48000-1; // tick on 1 ms - - - TIM6->ARR = 10000; // 10s - // Enable, One-Pulse Mode, Only overflow interrupt - TIM6->CR1 = TIM_CR1_CEN | TIM_CR1_OPM | TIM_CR1_URS; - TIM6->EGR = TIM_EGR_UG; - NVIC_EnableIRQ(TIM6_DAC_IRQn); - puts("Saving power init done\n"); - TIM6->DIER = TIM_DIER_UIE; - TIM6->CR1 |= TIM_CR1_CEN; -} - -void TIM6_DAC_IRQHandler(void) { - //Timeout switch to power saving mode. - if (TIM6->SR & TIM_SR_UIF) { - TIM6->SR = 0; -#ifdef EON - if (power_save_status == POWER_SAVE_STATUS_DISABLED) { - power_save_enable(); - } else if (power_save_status == POWER_SAVE_STATUS_SWITCHING) { - power_save_enable_can_wake(); - } -#endif - } else { - TIM6->CR1 |= TIM_CR1_CEN; - } -} diff --git a/panda/board/safety.h b/panda/board/safety.h index 5543333e3..3addc6536 100644 --- a/panda/board/safety.h +++ b/panda/board/safety.h @@ -5,13 +5,11 @@ struct sample_t { int max; } sample_t_default = {{0}, 0, 0}; -// no float support in STM32F2 micros (cortex-m3) -#ifdef PANDA +// safety code requires floats struct lookup_t { float x[3]; float y[3]; }; -#endif void safety_rx_hook(CAN_FIFOMailBox_TypeDef *to_push); int safety_tx_hook(CAN_FIFOMailBox_TypeDef *to_send); @@ -27,21 +25,14 @@ int driver_limit_check(int val, int val_last, struct sample_t *val_driver, const int MAX, const int MAX_RATE_UP, const int MAX_RATE_DOWN, const int MAX_ALLOWANCE, const int DRIVER_FACTOR); int rt_rate_limit_check(int val, int val_last, const int MAX_RT_DELTA); -#ifdef PANDA float interpolate(struct lookup_t xy, float x); -void lline_relay_init (void); -void lline_relay_release (void); -void set_lline_output(int to_set); -#endif - typedef void (*safety_hook_init)(int16_t param); typedef void (*rx_hook)(CAN_FIFOMailBox_TypeDef *to_push); typedef int (*tx_hook)(CAN_FIFOMailBox_TypeDef *to_send); typedef int (*tx_lin_hook)(int lin_num, uint8_t *data, int len); typedef int (*ign_hook)(); typedef int (*fwd_hook)(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd); -typedef int (*relay_hook)(); typedef struct { safety_hook_init init; @@ -50,21 +41,23 @@ typedef struct { tx_hook tx; tx_lin_hook tx_lin; fwd_hook fwd; - relay_hook relay; } safety_hooks; // This can be set by the safety hooks. int controls_allowed = 0; +int gas_interceptor_detected = 0; +int gas_interceptor_prev = 0; + +// This is set by USB command 0xdf +int long_controls_allowed = 1; // Include the actual safety policies. #include "safety/safety_defaults.h" #include "safety/safety_honda.h" #include "safety/safety_toyota.h" -#ifdef PANDA #include "safety/safety_toyota_ipas.h" #include "safety/safety_tesla.h" #include "safety/safety_gm_ascm.h" -#endif #include "safety/safety_gm.h" #include "safety/safety_ford.h" #include "safety/safety_cadillac.h" @@ -97,10 +90,6 @@ int safety_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { return current_hooks->fwd(bus_num, to_fwd); } -int safety_relay_hook(void) { - return current_hooks->relay(); -} - typedef struct { uint16_t id; const safety_hooks *hooks; @@ -119,7 +108,6 @@ typedef struct { #define SAFETY_SUBARU 10 #define SAFETY_GM_ASCM 0x1334 #define SAFETY_TOYOTA_IPAS 0x1335 -#define SAFETY_TOYOTA_NOLIMITS 0x1336 #define SAFETY_ALLOUTPUT 0x1337 #define SAFETY_ELM327 0xE327 @@ -134,12 +122,9 @@ const safety_hook_config safety_hook_registry[] = { {SAFETY_HYUNDAI, &hyundai_hooks}, {SAFETY_CHRYSLER, &chrysler_hooks}, {SAFETY_SUBARU, &subaru_hooks}, - {SAFETY_TOYOTA_NOLIMITS, &toyota_nolimits_hooks}, -#ifdef PANDA {SAFETY_TOYOTA_IPAS, &toyota_ipas_hooks}, {SAFETY_GM_ASCM, &gm_ascm_hooks}, {SAFETY_TESLA, &tesla_hooks}, -#endif {SAFETY_ALLOUTPUT, &alloutput_hooks}, {SAFETY_ELM327, &elm327_hooks}, }; @@ -239,7 +224,6 @@ int rt_rate_limit_check(int val, int val_last, const int MAX_RT_DELTA) { } -#ifdef PANDA // interp function that holds extreme values float interpolate(struct lookup_t xy, float x) { int size = sizeof(xy.x) / sizeof(xy.x[0]); @@ -264,4 +248,3 @@ float interpolate(struct lookup_t xy, float x) { return xy.y[size - 1]; } } -#endif diff --git a/panda/board/safety/safety_cadillac.h b/panda/board/safety/safety_cadillac.h index 0e6636a1a..2a2d8b985 100644 --- a/panda/board/safety/safety_cadillac.h +++ b/panda/board/safety/safety_cadillac.h @@ -115,9 +115,6 @@ static int cadillac_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { static void cadillac_init(int16_t param) { controls_allowed = 0; cadillac_ign = 0; - #ifdef PANDA - lline_relay_release(); - #endif } static int cadillac_ign_hook() { @@ -131,5 +128,4 @@ const safety_hooks cadillac_hooks = { .tx_lin = nooutput_tx_lin_hook, .ignition = cadillac_ign_hook, .fwd = alloutput_fwd_hook, - .relay = nooutput_relay_hook, }; diff --git a/panda/board/safety/safety_chrysler.h b/panda/board/safety/safety_chrysler.h index a8826b915..4af588401 100644 --- a/panda/board/safety/safety_chrysler.h +++ b/panda/board/safety/safety_chrysler.h @@ -127,9 +127,6 @@ static int chrysler_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { static void chrysler_init(int16_t param) { chrysler_camera_detected = 0; - #ifdef PANDA - lline_relay_release(); - #endif } static int chrysler_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { @@ -153,5 +150,4 @@ const safety_hooks chrysler_hooks = { .tx_lin = nooutput_tx_lin_hook, .ignition = default_ign_hook, .fwd = chrysler_fwd_hook, - .relay = nooutput_relay_hook, }; diff --git a/panda/board/safety/safety_defaults.h b/panda/board/safety/safety_defaults.h index 88d31a7de..196df65d2 100644 --- a/panda/board/safety/safety_defaults.h +++ b/panda/board/safety/safety_defaults.h @@ -8,9 +8,6 @@ int default_ign_hook() { static void nooutput_init(int16_t param) { controls_allowed = 0; - #ifdef PANDA - lline_relay_release(); - #endif } static int nooutput_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { @@ -25,10 +22,6 @@ static int nooutput_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { return -1; } -static int nooutput_relay_hook(int to_set) { - return false; -} - const safety_hooks nooutput_hooks = { .init = nooutput_init, .rx = default_rx_hook, @@ -36,16 +29,12 @@ const safety_hooks nooutput_hooks = { .tx_lin = nooutput_tx_lin_hook, .ignition = default_ign_hook, .fwd = nooutput_fwd_hook, - .relay = nooutput_relay_hook, }; // *** all output safety mode *** static void alloutput_init(int16_t param) { controls_allowed = 1; - #ifdef PANDA - lline_relay_release(); - #endif } static int alloutput_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { @@ -60,10 +49,6 @@ static int alloutput_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { return -1; } -static int alloutput_relay_hook(int to_set) { - return true; -} - const safety_hooks alloutput_hooks = { .init = alloutput_init, .rx = default_rx_hook, @@ -71,5 +56,4 @@ const safety_hooks alloutput_hooks = { .tx_lin = alloutput_tx_lin_hook, .ignition = default_ign_hook, .fwd = alloutput_fwd_hook, - .relay = alloutput_relay_hook, }; diff --git a/panda/board/safety/safety_elm327.h b/panda/board/safety/safety_elm327.h index e89783bcc..823d553dd 100644 --- a/panda/board/safety/safety_elm327.h +++ b/panda/board/safety/safety_elm327.h @@ -1,5 +1,3 @@ -static void elm327_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) {} - static int elm327_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { //All ELM traffic must appear on CAN0 if(((to_send->RDTR >> 4) & 0xf) != 0) return 0; @@ -27,20 +25,11 @@ static int elm327_tx_lin_hook(int lin_num, uint8_t *data, int len) { return true; } -static void elm327_init(int16_t param) { - controls_allowed = 1; -} - -static int elm327_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { - return -1; -} - const safety_hooks elm327_hooks = { - .init = elm327_init, - .rx = elm327_rx_hook, + .init = nooutput_init, + .rx = default_rx_hook, .tx = elm327_tx_hook, .tx_lin = elm327_tx_lin_hook, .ignition = default_ign_hook, - .fwd = elm327_fwd_hook, - .relay = nooutput_relay_hook, + .fwd = nooutput_fwd_hook, }; diff --git a/panda/board/safety/safety_ford.h b/panda/board/safety/safety_ford.h index 1d3f16d06..075029fb6 100644 --- a/panda/board/safety/safety_ford.h +++ b/panda/board/safety/safety_ford.h @@ -90,5 +90,4 @@ const safety_hooks ford_hooks = { .tx_lin = nooutput_tx_lin_hook, .ignition = default_ign_hook, .fwd = nooutput_fwd_hook, - .relay = nooutput_relay_hook, }; diff --git a/panda/board/safety/safety_gm.h b/panda/board/safety/safety_gm.h index 396fb8770..996161127 100644 --- a/panda/board/safety/safety_gm.h +++ b/panda/board/safety/safety_gm.h @@ -101,7 +101,7 @@ static void gm_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { // exit controls on rising edge of gas press if (addr == 417) { int gas = to_push->RDHR & 0xFF0000; - if (gas && !gm_gas_prev) { + if (gas && !gm_gas_prev && long_controls_allowed) { controls_allowed = 0; } gm_gas_prev = gas; @@ -148,7 +148,7 @@ static int gm_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { int rdlr = to_send->RDLR; int brake = ((rdlr & 0xF) << 8) + ((rdlr & 0xFF00) >> 8); brake = (0x1000 - brake) & 0xFFF; - if (current_controls_allowed) { + if (current_controls_allowed && long_controls_allowed) { if (brake > GM_MAX_BRAKE) return 0; } else { if (brake != 0) return 0; @@ -212,7 +212,7 @@ static int gm_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { int rdlr = to_send->RDLR; int gas_regen = ((rdlr & 0x7F0000) >> 11) + ((rdlr & 0xF8000000) >> 27); int apply = rdlr & 1; - if (current_controls_allowed) { + if (current_controls_allowed && long_controls_allowed) { if (gas_regen > GM_MAX_GAS) return 0; } else { // Disabled message is !engaed with gas @@ -228,9 +228,6 @@ static int gm_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { static void gm_init(int16_t param) { controls_allowed = 0; gm_ignition_started = 0; - #ifdef PANDA - lline_relay_release(); - #endif } static int gm_ign_hook() { @@ -244,5 +241,4 @@ const safety_hooks gm_hooks = { .tx_lin = nooutput_tx_lin_hook, .ignition = gm_ign_hook, .fwd = nooutput_fwd_hook, - .relay = nooutput_relay_hook, }; diff --git a/panda/board/safety/safety_gm_ascm.h b/panda/board/safety/safety_gm_ascm.h index b145466d9..70a042ec5 100644 --- a/panda/board/safety/safety_gm_ascm.h +++ b/panda/board/safety/safety_gm_ascm.h @@ -48,6 +48,5 @@ const safety_hooks gm_ascm_hooks = { .tx_lin = nooutput_tx_lin_hook, .ignition = default_ign_hook, .fwd = gm_ascm_fwd_hook, - .relay = nooutput_relay_hook, }; diff --git a/panda/board/safety/safety_honda.h b/panda/board/safety/safety_honda.h index 40c6917b0..3aeeefe83 100644 --- a/panda/board/safety/safety_honda.h +++ b/panda/board/safety/safety_honda.h @@ -7,15 +7,11 @@ // brake rising edge // brake > 0mph -// these are set in the Honda safety hooks...this is the wrong place -const int gas_interceptor_threshold = 328; -int gas_interceptor_detected = 0; -int brake_prev = 0; -int gas_prev = 0; -int gas_interceptor_prev = 0; -int ego_speed = 0; -// TODO: auto-detect bosch hardware based on CAN messages? -bool bosch_hardware = false; +const int HONDA_GAS_INTERCEPTOR_THRESHOLD = 328; // ratio between offset and gain from dbc file +int honda_brake_prev = 0; +int honda_gas_prev = 0; +int honda_ego_speed = 0; +bool honda_bosch_hardware = false; bool honda_alt_brake_msg = false; static void honda_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { @@ -23,7 +19,7 @@ static void honda_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { // sample speed if ((to_push->RIR>>21) == 0x158) { // first 2 bytes - ego_speed = to_push->RDLR & 0xFFFF; + honda_ego_speed = to_push->RDLR & 0xFFFF; } // state machine to enter and exit controls @@ -49,10 +45,10 @@ static void honda_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { // speed > 0 if (IS_USER_BRAKE_MSG(to_push)) { int brake = USER_BRAKE_VALUE(to_push); - if (brake && (!(brake_prev) || ego_speed)) { + if (brake && (!(honda_brake_prev) || honda_ego_speed)) { controls_allowed = 0; } - brake_prev = brake; + honda_brake_prev = brake; } // exit controls on rising edge of gas press if interceptor (0x201 w/ len = 6) @@ -60,8 +56,9 @@ static void honda_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { if ((to_push->RIR>>21) == 0x201 && (to_push->RDTR & 0xf) == 6) { gas_interceptor_detected = 1; int gas_interceptor = ((to_push->RDLR & 0xFF) << 8) | ((to_push->RDLR & 0xFF00) >> 8); - if ((gas_interceptor > gas_interceptor_threshold) && - (gas_interceptor_prev <= gas_interceptor_threshold)) { + if ((gas_interceptor > HONDA_GAS_INTERCEPTOR_THRESHOLD) && + (gas_interceptor_prev <= HONDA_GAS_INTERCEPTOR_THRESHOLD) && + long_controls_allowed) { controls_allowed = 0; } gas_interceptor_prev = gas_interceptor; @@ -71,10 +68,10 @@ static void honda_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { if (!gas_interceptor_detected) { if ((to_push->RIR>>21) == 0x17C) { int gas = to_push->RDLR & 0xFF; - if (gas && !(gas_prev)) { + if (gas && !(honda_gas_prev) && long_controls_allowed) { controls_allowed = 0; } - gas_prev = gas; + honda_gas_prev = gas; } } } @@ -89,13 +86,13 @@ static int honda_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { // disallow actuator commands if gas or brake (with vehicle moving) are pressed // and the the latching controls_allowed flag is True - int pedal_pressed = gas_prev || (gas_interceptor_prev > gas_interceptor_threshold) || - (brake_prev && ego_speed); + int pedal_pressed = honda_gas_prev || (gas_interceptor_prev > HONDA_GAS_INTERCEPTOR_THRESHOLD) || + (honda_brake_prev && honda_ego_speed); int current_controls_allowed = controls_allowed && !(pedal_pressed); // BRAKE: safety check if ((to_send->RIR>>21) == 0x1FA) { - if (current_controls_allowed) { + if (current_controls_allowed && long_controls_allowed) { if ((to_send->RDLR & 0xFFFFFF3F) != to_send->RDLR) return 0; } else { if ((to_send->RDLR & 0xFFFF0000) != to_send->RDLR) return 0; @@ -113,7 +110,7 @@ static int honda_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { // GAS: safety check if ((to_send->RIR>>21) == 0x200) { - if (current_controls_allowed) { + if (current_controls_allowed && long_controls_allowed) { // all messages are fine here } else { if ((to_send->RDLR & 0xFFFF0000) != to_send->RDLR) return 0; @@ -123,7 +120,7 @@ static int honda_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { // FORCE CANCEL: safety check only relevant when spamming the cancel button in Bosch HW // ensuring that only the cancel button press is sent (VAL 2) when controls are off. // This avoids unintended engagements while still allowing resume spam - if (((to_send->RIR>>21) == 0x296) && bosch_hardware && + if (((to_send->RIR>>21) == 0x296) && honda_bosch_hardware && !current_controls_allowed && ((to_send->RDTR >> 4) & 0xFF) == 0) { if (((to_send->RDLR >> 5) & 0x7) != 2) return 0; } @@ -134,21 +131,15 @@ static int honda_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { static void honda_init(int16_t param) { controls_allowed = 0; - bosch_hardware = false; + honda_bosch_hardware = false; honda_alt_brake_msg = false; - #ifdef PANDA - lline_relay_release(); - #endif } static void honda_bosch_init(int16_t param) { controls_allowed = 0; - bosch_hardware = true; + honda_bosch_hardware = true; // Checking for alternate brake override from safety parameter honda_alt_brake_msg = param == 1 ? true : false; - #ifdef PANDA - lline_relay_release(); - #endif } static int honda_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { @@ -159,11 +150,15 @@ static int honda_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { int addr = to_fwd->RIR>>21; if (bus_num == 0) { return 2; - } else if (bus_num == 2 && addr != 0xE4 && addr != 0x194 && addr != 0x1FA && - addr != 0x30C && addr != 0x33D && addr != 0x39F) { + } else if (bus_num == 2) { + // block stock lkas messages and stock acc messages (if OP is doing ACC) + int is_lkas_msg = (addr == 0xE4 || addr == 0x194 || addr == 0x33D); + int is_acc_msg = (addr == 0x1FA || addr == 0x30C || addr == 0x39F); + if (is_lkas_msg || (is_acc_msg && long_controls_allowed)) { + return -1; + } return 0; } - return -1; } @@ -182,7 +177,6 @@ const safety_hooks honda_hooks = { .tx_lin = nooutput_tx_lin_hook, .ignition = default_ign_hook, .fwd = honda_fwd_hook, - .relay = nooutput_relay_hook, }; const safety_hooks honda_bosch_hooks = { @@ -192,5 +186,4 @@ const safety_hooks honda_bosch_hooks = { .tx_lin = nooutput_tx_lin_hook, .ignition = default_ign_hook, .fwd = honda_bosch_fwd_hook, - .relay = nooutput_relay_hook, }; diff --git a/panda/board/safety/safety_hyundai.h b/panda/board/safety/safety_hyundai.h index 9470e34d1..b67632141 100644 --- a/panda/board/safety/safety_hyundai.h +++ b/panda/board/safety/safety_hyundai.h @@ -152,9 +152,6 @@ static int hyundai_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { static void hyundai_init(int16_t param) { controls_allowed = 0; hyundai_giraffe_switch_2 = 0; - #ifdef PANDA - lline_relay_release(); - #endif } const safety_hooks hyundai_hooks = { @@ -164,5 +161,4 @@ const safety_hooks hyundai_hooks = { .tx_lin = nooutput_tx_lin_hook, .ignition = default_ign_hook, .fwd = hyundai_fwd_hook, - .relay = nooutput_relay_hook, }; diff --git a/panda/board/safety/safety_subaru.h b/panda/board/safety/safety_subaru.h index 5d2bd23d2..e64c77719 100644 --- a/panda/board/safety/safety_subaru.h +++ b/panda/board/safety/safety_subaru.h @@ -15,9 +15,6 @@ uint32_t subaru_ts_last = 0; struct sample_t subaru_torque_driver; // last few driver torques measured static void subaru_init(int16_t param) { - #ifdef PANDA - lline_relay_init(); - #endif } static void subaru_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { @@ -142,5 +139,4 @@ const safety_hooks subaru_hooks = { .tx_lin = nooutput_tx_lin_hook, .ignition = default_ign_hook, .fwd = subaru_fwd_hook, - .relay = alloutput_relay_hook, }; diff --git a/panda/board/safety/safety_tesla.h b/panda/board/safety/safety_tesla.h index 882a509f5..430a42ce9 100644 --- a/panda/board/safety/safety_tesla.h +++ b/panda/board/safety/safety_tesla.h @@ -219,20 +219,11 @@ static int tesla_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) return true; } -static int tesla_tx_lin_hook(int lin_num, uint8_t *data, int len) -{ - // LIN is not used on the Tesla - return false; -} - static void tesla_init(int16_t param) { controls_allowed = 0; tesla_ignition_started = 0; gmlan_switch_init(1); //init the gmlan switch with 1s timeout enabled - #ifdef PANDA - lline_relay_release(); - #endif } static int tesla_ign_hook() @@ -281,11 +272,10 @@ static int tesla_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) } const safety_hooks tesla_hooks = { - .init = tesla_init, - .rx = tesla_rx_hook, - .tx = tesla_tx_hook, - .tx_lin = tesla_tx_lin_hook, - .ignition = tesla_ign_hook, - .fwd = tesla_fwd_hook, - .relay = nooutput_relay_hook, + .init = tesla_init, + .rx = tesla_rx_hook, + .tx = tesla_tx_hook, + .tx_lin = nooutput_tx_lin_hook, + .ignition = tesla_ign_hook, + .fwd = tesla_fwd_hook, }; diff --git a/panda/board/safety/safety_toyota.h b/panda/board/safety/safety_toyota.h index cbc838608..2c9e062f7 100644 --- a/panda/board/safety/safety_toyota.h +++ b/panda/board/safety/safety_toyota.h @@ -1,6 +1,3 @@ -int toyota_giraffe_switch_1 = 0; // is giraffe switch 1 high? -int toyota_camera_forwarded = 0; // should we forward the camera bus? - // global torque limit const int TOYOTA_MAX_TORQUE = 1500; // max torque cmd allowed ever @@ -19,15 +16,19 @@ const int TOYOTA_RT_INTERVAL = 250000; // 250ms between real time checks const int TOYOTA_MAX_ACCEL = 1500; // 1.5 m/s2 const int TOYOTA_MIN_ACCEL = -3000; // 3.0 m/s2 -// global actuation limit state -int toyota_actuation_limits = 1; // by default steer limits are imposed +const int TOYOTA_GAS_INTERCEPTOR_THRESHOLD = 475; // ratio between offset and gain from dbc file + +// global actuation limit states int toyota_dbc_eps_torque_factor = 100; // conversion factor for STEER_TORQUE_EPS in %: see dbc file -// state of torque limits +// states +int toyota_giraffe_switch_1 = 0; // is giraffe switch 1 high? +int toyota_camera_forwarded = 0; // should we forward the camera bus? int toyota_desired_torque_last = 0; // last desired steer torque int toyota_rt_torque_last = 0; // last desired torque for real time check uint32_t toyota_ts_last = 0; int toyota_cruise_engaged_last = 0; // cruise state +int toyota_gas_prev = 0; struct sample_t toyota_torque_meas; // last 3 motor torques produced by the eps @@ -40,23 +41,40 @@ static void toyota_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { // scale by dbc_factor torque_meas_new = (torque_meas_new * toyota_dbc_eps_torque_factor) / 100; - // increase torque_meas by 1 to be conservative on rounding - torque_meas_new += (torque_meas_new > 0 ? 1 : -1); - // update array of sample update_sample(&toyota_torque_meas, torque_meas_new); + + // increase torque_meas by 1 to be conservative on rounding + toyota_torque_meas.min--; + toyota_torque_meas.max++; } // enter controls on rising edge of ACC, exit controls on ACC off if ((to_push->RIR>>21) == 0x1D2) { // 5th bit is CRUISE_ACTIVE int cruise_engaged = to_push->RDLR & 0x20; - if (cruise_engaged && !toyota_cruise_engaged_last) { - controls_allowed = 1; - } else if (!cruise_engaged) { + // 4th bit is GAS_RELEASED + int gas = !(to_push->RDLR & 0x10); + if (!cruise_engaged || + (gas && !toyota_gas_prev && !gas_interceptor_detected && long_controls_allowed)) { controls_allowed = 0; + } else if (cruise_engaged && !toyota_cruise_engaged_last) { + controls_allowed = 1; } toyota_cruise_engaged_last = cruise_engaged; + toyota_gas_prev = gas; + } + + // exit controls on rising edge of gas press if interceptor (0x201) + if ((to_push->RIR>>21) == 0x201) { + gas_interceptor_detected = 1; + int gas_interceptor = ((to_push->RDLR & 0xFF) << 8) | ((to_push->RDLR & 0xFF00) >> 8); + if ((gas_interceptor > TOYOTA_GAS_INTERCEPTOR_THRESHOLD) && + (gas_interceptor_prev <= TOYOTA_GAS_INTERCEPTOR_THRESHOLD) && + long_controls_allowed) { + controls_allowed = 0; + } + gas_interceptor_prev = gas_interceptor; } int bus = (to_push->RDTR >> 4) & 0xF; @@ -81,7 +99,7 @@ static int toyota_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { // GAS PEDAL: safety check if ((to_send->RIR>>21) == 0x200) { - if (controls_allowed && toyota_actuation_limits) { + if (controls_allowed && long_controls_allowed) { // all messages are fine here } else { if ((to_send->RDLR & 0xFFFF0000) != to_send->RDLR) return 0; @@ -92,10 +110,10 @@ static int toyota_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { if ((to_send->RIR>>21) == 0x343) { int desired_accel = ((to_send->RDLR & 0xFF) << 8) | ((to_send->RDLR >> 8) & 0xFF); desired_accel = to_signed(desired_accel, 16); - if (controls_allowed && toyota_actuation_limits) { + if (controls_allowed && long_controls_allowed) { int violation = max_limit_check(desired_accel, TOYOTA_MAX_ACCEL, TOYOTA_MIN_ACCEL); if (violation) return 0; - } else if (!controls_allowed && (desired_accel != 0)) { + } else if (desired_accel != 0) { return 0; } } @@ -108,8 +126,7 @@ static int toyota_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { uint32_t ts = TIM2->CNT; - // only check if controls are allowed and actuation_limits are imposed - if (controls_allowed && toyota_actuation_limits) { + if (controls_allowed) { // *** global torque limit check *** violation |= max_limit_check(desired_torque, TOYOTA_MAX_TORQUE, -TOYOTA_MAX_TORQUE); @@ -156,25 +173,27 @@ static int toyota_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { static void toyota_init(int16_t param) { controls_allowed = 0; - toyota_actuation_limits = 1; toyota_giraffe_switch_1 = 0; toyota_camera_forwarded = 0; toyota_dbc_eps_torque_factor = param; - #ifdef PANDA - lline_relay_release(); - #endif } static int toyota_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { - // forward cam to radar and viceversa if car, except lkas cmd and hud - // don't forward when switch 1 is high - if ((bus_num == 0 || bus_num == 2) && toyota_camera_forwarded && !toyota_giraffe_switch_1) { + if (toyota_camera_forwarded && !toyota_giraffe_switch_1) { int addr = to_fwd->RIR>>21; - bool is_lkas_msg = (addr == 0x2E4 || addr == 0x412) && bus_num == 2; - // in TSSP 2.0 the camera does ACC as well, so filter 0x343 - bool is_acc_msg = (addr == 0x343 && bus_num == 2); - return (is_lkas_msg || is_acc_msg)? -1 : (uint8_t)(~bus_num & 0x2); + if (bus_num == 0) { + return 2; + } else if (bus_num == 2) { + // block stock lkas messages and stock acc messages (if OP is doing ACC) + int is_lkas_msg = (addr == 0x2E4 || addr == 0x412); + // in TSSP 2.0 the camera does ACC as well, so filter 0x343 + int is_acc_msg = (addr == 0x343); + if (is_lkas_msg || (is_acc_msg && long_controls_allowed)) { + return -1; + } + return 0; + } } return -1; } @@ -186,26 +205,4 @@ const safety_hooks toyota_hooks = { .tx_lin = nooutput_tx_lin_hook, .ignition = default_ign_hook, .fwd = toyota_fwd_hook, - .relay = nooutput_relay_hook, -}; - -static void toyota_nolimits_init(int16_t param) { - controls_allowed = 0; - toyota_actuation_limits = 0; - toyota_giraffe_switch_1 = 0; - toyota_camera_forwarded = 0; - toyota_dbc_eps_torque_factor = param; - #ifdef PANDA - lline_relay_release(); - #endif -} - -const safety_hooks toyota_nolimits_hooks = { - .init = toyota_nolimits_init, - .rx = toyota_rx_hook, - .tx = toyota_tx_hook, - .tx_lin = nooutput_tx_lin_hook, - .ignition = default_ign_hook, - .fwd = toyota_fwd_hook, - .relay = nooutput_relay_hook, }; diff --git a/panda/board/safety/safety_toyota_ipas.h b/panda/board/safety/safety_toyota_ipas.h index 13e664c0f..2f0b42f64 100644 --- a/panda/board/safety/safety_toyota_ipas.h +++ b/panda/board/safety/safety_toyota_ipas.h @@ -152,5 +152,4 @@ const safety_hooks toyota_ipas_hooks = { .tx_lin = nooutput_tx_lin_hook, .ignition = default_ign_hook, .fwd = toyota_fwd_hook, - .relay = nooutput_relay_hook, }; diff --git a/panda/board/spi_flasher.h b/panda/board/spi_flasher.h index 179a095b9..48e00aa22 100644 --- a/panda/board/spi_flasher.h +++ b/panda/board/spi_flasher.h @@ -2,7 +2,9 @@ uint32_t *prog_ptr = NULL; int unlocked = 0; +#ifdef uart_ring void debug_ring_callback(uart_ring *ring) {} +#endif int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) { int resp_len = 0; @@ -46,7 +48,7 @@ int usb_cb_control_msg(USB_Setup_TypeDef *setup, uint8_t *resp, int hardwired) { break; // **** 0xd0: fetch serial number case 0xd0: - #ifdef PANDA + #ifdef STM32F4 // addresses are OTP if (setup->b.wValue.w == 1) { memcpy(resp, (void *)0x1fff79c0, 0x10); @@ -132,6 +134,7 @@ int spi_cb_rx(uint8_t *data, int len, uint8_t *data_out) { #ifdef PEDAL +#include "drivers/llcan.h" #define CAN CAN1 #define CAN_BL_INPUT 0x1 @@ -239,7 +242,7 @@ void CAN1_RX0_IRQHandler() { } void CAN1_SCE_IRQHandler() { - can_sce(CAN); + llcan_clear_send(CAN); } #endif @@ -264,8 +267,8 @@ void soft_flasher_start() { set_can_enable(CAN1, 1); // init can - can_silent = ALL_CAN_LIVE; - can_init(0); + llcan_set_speed(CAN1, 5000, false, false); + llcan_init(CAN1); #endif // A4,A5,A6,A7: setup SPI diff --git a/panda/buy.png b/panda/buy.png index 72c705742..a4a9e0fd4 100644 Binary files a/panda/buy.png and b/panda/buy.png differ diff --git a/panda/examples/query_vin_and_stats.py b/panda/examples/query_vin_and_stats.py index 09a6289bf..f3d6c198a 100755 --- a/panda/examples/query_vin_and_stats.py +++ b/panda/examples/query_vin_and_stats.py @@ -3,7 +3,7 @@ import time import struct from panda import Panda from hexdump import hexdump -from panda.isotp import isotp_send, isotp_recv +from panda.python.isotp import isotp_send, isotp_recv # 0x7e0 = Toyota # 0x18DB33F1 for Honda? @@ -33,7 +33,7 @@ if __name__ == "__main__": panda.can_clear(0) # 09 02 = Get VIN - isotp_send(panda, "\x09\x02", 0x7e0) + isotp_send(panda, "\x09\x02", 0x7df) ret = isotp_recv(panda, 0x7e8) hexdump(ret) print "VIN: %s" % ret[2:] diff --git a/panda/python/__init__.py b/panda/python/__init__.py index 8c0bc5a9a..bfca642e8 100644 --- a/panda/python/__init__.py +++ b/panda/python/__init__.py @@ -392,9 +392,6 @@ class Panda(object): elif bus in [Panda.GMLAN_CAN2, Panda.GMLAN_CAN3]: self._handle.controlWrite(Panda.REQUEST_OUT, 0xdb, 1, bus, b'') - def set_lline_relay(self, enable): - self._handle.controlWrite(Panda.REQUEST_OUT, 0xf3, int(enable), 0, b'') - def set_can_loopback(self, enable): # set can loopback mode for all buses self._handle.controlWrite(Panda.REQUEST_OUT, 0xe5, int(enable), 0, b'') diff --git a/panda/run_automated_tests.sh b/panda/run_automated_tests.sh index 63d9b6531..4e07d329c 100755 --- a/panda/run_automated_tests.sh +++ b/panda/run_automated_tests.sh @@ -6,4 +6,9 @@ else TESTSUITE_NAME="Panda_Test-DEV" fi -PYTHONPATH="." nosetests -v --with-xunit --xunit-file=./$TEST_FILENAME --xunit-testsuite-name=$TESTSUITE_NAME -s tests/automated/$1*.py +cd boardesp +make flashall +cd .. + + +PYTHONPATH="." python $(which nosetests) -v --with-xunit --xunit-file=./$TEST_FILENAME --xunit-testsuite-name=$TESTSUITE_NAME -s tests/automated/$1*.py diff --git a/panda/tests/automated/0_builds.py b/panda/tests/automated/0_builds.py index d5e434a2c..df4186cce 100644 --- a/panda/tests/automated/0_builds.py +++ b/panda/tests/automated/0_builds.py @@ -1,12 +1,6 @@ import os from panda import build_st -def test_build_legacy(): - build_st("obj/comma.bin", "Makefile.legacy") - -def test_build_bootstub_legacy(): - build_st("obj/bootstub.comma.bin", "Makefile.legacy") - def test_build_panda(): build_st("obj/panda.bin") diff --git a/panda/tests/automated/3_wifi.py b/panda/tests/automated/3_wifi.py index 6578903aa..1251663ba 100644 --- a/panda/tests/automated/3_wifi.py +++ b/panda/tests/automated/3_wifi.py @@ -29,7 +29,7 @@ def test_connect_wifi(serial=None): @panda_color_to_serial def test_flash_wifi(serial=None): connect_wifi(serial) - assert Panda.flash_ota_wifi(release=True), "OTA Wifi Flash Failed" + assert Panda.flash_ota_wifi(release=False), "OTA Wifi Flash Failed" connect_wifi(serial) @test_white diff --git a/panda/tests/build_strict/Dockerfile b/panda/tests/build_strict/Dockerfile new file mode 100644 index 000000000..b1c75c025 --- /dev/null +++ b/panda/tests/build_strict/Dockerfile @@ -0,0 +1,9 @@ +FROM ubuntu:16.04 + +RUN apt-get update && apt-get install -y gcc-arm-none-eabi libnewlib-arm-none-eabi python python-pip gcc g++ + +RUN pip install pycrypto==2.6.1 + +COPY . /panda + +WORKDIR /panda diff --git a/panda/tests/misra/Dockerfile b/panda/tests/misra/Dockerfile new file mode 100644 index 000000000..e63cc7e9e --- /dev/null +++ b/panda/tests/misra/Dockerfile @@ -0,0 +1,6 @@ +FROM ubuntu:16.04 + +RUN apt-get update && apt-get install -y make python python-pip git +COPY tests/safety/requirements.txt /panda/tests/safety/requirements.txt +RUN pip install -r /panda/tests/safety/requirements.txt +COPY . /panda diff --git a/panda/tests/misra/test_misra.sh b/panda/tests/misra/test_misra.sh new file mode 100755 index 000000000..5d2650dc0 --- /dev/null +++ b/panda/tests/misra/test_misra.sh @@ -0,0 +1,8 @@ +#!/bin/bash -e +git clone https://github.com/danmar/cppcheck.git || true +cd cppcheck +git checkout 29e5992e51ecf1ddba469c73a0eed0b28b131de5 +make -j4 +cd ../../../ +tests/misra/cppcheck/cppcheck --dump board/main.c +python tests/misra/cppcheck/addons/misra.py board/main.c.dump 2>/tmp/misra/output.txt || true diff --git a/panda/tests/safety/libpandasafety_py.py b/panda/tests/safety/libpandasafety_py.py index d8cb27cf8..84f3b00d0 100644 --- a/panda/tests/safety/libpandasafety_py.py +++ b/panda/tests/safety/libpandasafety_py.py @@ -32,6 +32,11 @@ typedef struct void set_controls_allowed(int c); int get_controls_allowed(void); +void set_long_controls_allowed(int c); +int get_long_controls_allowed(void); +void set_gas_interceptor_detected(int c); +int get_gas_interceptor_detetcted(void); +int get_gas_interceptor_prev(void); void set_timer(int t); void reset_angle_control(void); @@ -41,19 +46,20 @@ int toyota_tx_hook(CAN_FIFOMailBox_TypeDef *to_send); void toyota_init(int16_t param); int get_toyota_torque_meas_min(void); int get_toyota_torque_meas_max(void); +int get_toyota_gas_prev(void); void set_toyota_torque_meas(int min, int max); void set_toyota_desired_torque_last(int t); void set_toyota_rt_torque_last(int t); void init_tests_honda(void); -int get_ego_speed(void); +int get_honda_ego_speed(void); void honda_init(int16_t param); void honda_rx_hook(CAN_FIFOMailBox_TypeDef *to_push); int honda_tx_hook(CAN_FIFOMailBox_TypeDef *to_send); -int get_brake_prev(void); -int get_gas_prev(void); +int get_honda_brake_prev(void); +int get_honda_gas_prev(void); void set_honda_alt_brake_msg(bool); -void set_bosch_hardware(bool); +void set_honda_bosch_hardware(bool); void init_tests_cadillac(void); void cadillac_init(int16_t param); diff --git a/panda/tests/safety/test.c b/panda/tests/safety/test.c index 04e6576fb..ce75df82a 100644 --- a/panda/tests/safety/test.c +++ b/panda/tests/safety/test.c @@ -51,6 +51,14 @@ void set_controls_allowed(int c){ controls_allowed = c; } +void set_long_controls_allowed(int c){ + long_controls_allowed = c; +} + +void set_gas_interceptor_detected(int c){ + gas_interceptor_detected = c; +} + void reset_angle_control(void){ angle_control = 0; } @@ -59,6 +67,18 @@ int get_controls_allowed(void){ return controls_allowed; } +int get_long_controls_allowed(void){ + return long_controls_allowed; +} + +int get_gas_interceptor_detected(void){ + return gas_interceptor_detected; +} + +int get_gas_interceptor_prev(void){ + return gas_interceptor_prev; +} + void set_timer(int t){ timer.CNT = t; } @@ -101,6 +121,10 @@ int get_chrysler_torque_meas_max(void){ return chrysler_torque_meas.max; } +int get_toyota_gas_prev(void){ + return toyota_gas_prev; +} + int get_toyota_torque_meas_min(void){ return toyota_torque_meas.min; } @@ -157,24 +181,24 @@ void set_subaru_desired_torque_last(int t){ subaru_desired_torque_last = t; } -int get_ego_speed(void){ - return ego_speed; +int get_honda_ego_speed(void){ + return honda_ego_speed; } -int get_brake_prev(void){ - return brake_prev; +int get_honda_brake_prev(void){ + return honda_brake_prev; } -int get_gas_prev(void){ - return gas_prev; +int get_honda_gas_prev(void){ + return honda_gas_prev; } void set_honda_alt_brake_msg(bool c){ honda_alt_brake_msg = c; } -void set_bosch_hardware(bool c){ - bosch_hardware = c; +void set_honda_bosch_hardware(bool c){ + honda_bosch_hardware = c; } void init_tests_toyota(void){ @@ -232,10 +256,9 @@ void init_tests_subaru(void){ } void init_tests_honda(void){ - ego_speed = 0; - gas_interceptor_detected = 0; - brake_prev = 0; - gas_prev = 0; + honda_ego_speed = 0; + honda_brake_prev = 0; + honda_gas_prev = 0; } void set_gmlan_digital_output(int to_set){ @@ -247,11 +270,3 @@ void reset_gmlan_switch_timeout(void){ void gmlan_switch_init(int timeout_enable){ } -void lline_relay_init (void) { -} - -void lline_relay_release (void) { -} - -void set_lline_output(int to_set) { -} diff --git a/panda/tests/safety/test_gm.py b/panda/tests/safety/test_gm.py index 299de5a7e..ecdf40fed 100644 --- a/panda/tests/safety/test_gm.py +++ b/panda/tests/safety/test_gm.py @@ -138,10 +138,15 @@ class TestGmSafety(unittest.TestCase): self.safety.gm_rx_hook(self._brake_msg(False)) def test_disengage_on_gas(self): - self.safety.set_controls_allowed(1) - self.safety.gm_rx_hook(self._gas_msg(True)) - self.assertFalse(self.safety.get_controls_allowed()) - self.safety.gm_rx_hook(self._gas_msg(False)) + for long_controls_allowed in [0, 1]: + self.safety.set_long_controls_allowed(long_controls_allowed) + self.safety.set_controls_allowed(1) + self.safety.gm_rx_hook(self._gas_msg(True)) + if long_controls_allowed: + self.assertFalse(self.safety.get_controls_allowed()) + else: + self.assertTrue(self.safety.get_controls_allowed()) + self.safety.gm_rx_hook(self._gas_msg(False)) def test_allow_engage_with_gas_pressed(self): self.safety.gm_rx_hook(self._gas_msg(True)) @@ -151,22 +156,28 @@ class TestGmSafety(unittest.TestCase): self.safety.gm_rx_hook(self._gas_msg(False)) def test_brake_safety_check(self): - for enabled in [0, 1]: - for b in range(0, 500): - self.safety.set_controls_allowed(enabled) - if abs(b) > MAX_BRAKE or (not enabled and b != 0): - self.assertFalse(self.safety.gm_tx_hook(self._send_brake_msg(b))) - else: - self.assertTrue(self.safety.gm_tx_hook(self._send_brake_msg(b))) + for long_controls_allowed in [0, 1]: + self.safety.set_long_controls_allowed(long_controls_allowed) + for enabled in [0, 1]: + for b in range(0, 500): + self.safety.set_controls_allowed(enabled) + if abs(b) > MAX_BRAKE or ((not enabled or not long_controls_allowed) and b != 0): + self.assertFalse(self.safety.gm_tx_hook(self._send_brake_msg(b))) + else: + self.assertTrue(self.safety.gm_tx_hook(self._send_brake_msg(b))) + self.safety.set_long_controls_allowed(True) def test_gas_safety_check(self): - for enabled in [0, 1]: - for g in range(0, 2**12-1): - self.safety.set_controls_allowed(enabled) - if abs(g) > MAX_GAS or (not enabled and g != MAX_REGEN): - self.assertFalse(self.safety.gm_tx_hook(self._send_gas_msg(g))) - else: - self.assertTrue(self.safety.gm_tx_hook(self._send_gas_msg(g))) + for long_controls_allowed in [0, 1]: + self.safety.set_long_controls_allowed(long_controls_allowed) + for enabled in [0, 1]: + for g in range(0, 2**12-1): + self.safety.set_controls_allowed(enabled) + if abs(g) > MAX_GAS or ((not enabled or not long_controls_allowed) and g != MAX_REGEN): + self.assertFalse(self.safety.gm_tx_hook(self._send_gas_msg(g))) + else: + self.assertTrue(self.safety.gm_tx_hook(self._send_gas_msg(g))) + self.safety.set_long_controls_allowed(True) def test_steer_safety_check(self): for enabled in [0, 1]: diff --git a/panda/tests/safety/test_honda.py b/panda/tests/safety/test_honda.py index 48b678eaa..4e131f2fc 100755 --- a/panda/tests/safety/test_honda.py +++ b/panda/tests/safety/test_honda.py @@ -3,6 +3,7 @@ import unittest import numpy as np import libpandasafety_py +MAX_BRAKE = 255 class TestHondaSafety(unittest.TestCase): @classmethod @@ -49,14 +50,15 @@ class TestHondaSafety(unittest.TestCase): def _send_brake_msg(self, brake): to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') to_send[0].RIR = 0x1FA << 21 - to_send[0].RDLR = brake + to_send[0].RDLR = ((brake & 0x3) << 8) | ((brake & 0x3FF) >> 2) return to_send - def _send_gas_msg(self, gas): + def _send_interceptor_msg(self, gas, addr): to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') - to_send[0].RIR = 0x200 << 21 - to_send[0].RDLR = gas + to_send[0].RIR = addr << 21 + to_send[0].RDTR = 6 + to_send[0].RDLR = ((gas & 0xff) << 8) | ((gas & 0xff00) >> 8) return to_send @@ -89,14 +91,14 @@ class TestHondaSafety(unittest.TestCase): self.assertFalse(self.safety.get_controls_allowed()) def test_sample_speed(self): - self.assertEqual(0, self.safety.get_ego_speed()) + self.assertEqual(0, self.safety.get_honda_ego_speed()) self.safety.honda_rx_hook(self._speed_msg(100)) - self.assertEqual(100, self.safety.get_ego_speed()) + self.assertEqual(100, self.safety.get_honda_ego_speed()) def test_prev_brake(self): - self.assertFalse(self.safety.get_brake_prev()) + self.assertFalse(self.safety.get_honda_brake_prev()) self.safety.honda_rx_hook(self._brake_msg(True)) - self.assertTrue(self.safety.get_brake_prev()) + self.assertTrue(self.safety.get_honda_brake_prev()) def test_disengage_on_brake(self): self.safety.set_controls_allowed(1) @@ -133,14 +135,30 @@ class TestHondaSafety(unittest.TestCase): self.assertFalse(self.safety.get_controls_allowed()) def test_prev_gas(self): - self.assertFalse(self.safety.get_gas_prev()) + self.safety.honda_rx_hook(self._gas_msg(False)) + self.assertFalse(self.safety.get_honda_gas_prev()) self.safety.honda_rx_hook(self._gas_msg(True)) - self.assertTrue(self.safety.get_gas_prev()) + self.assertTrue(self.safety.get_honda_gas_prev()) + + def test_prev_gas_interceptor(self): + self.safety.honda_rx_hook(self._send_interceptor_msg(0x0, 0x201)) + self.assertFalse(self.safety.get_gas_interceptor_prev()) + self.safety.honda_rx_hook(self._send_interceptor_msg(0x1000, 0x201)) + self.assertTrue(self.safety.get_gas_interceptor_prev()) + self.safety.honda_rx_hook(self._send_interceptor_msg(0x0, 0x201)) + self.safety.set_gas_interceptor_detected(False) def test_disengage_on_gas(self): - self.safety.set_controls_allowed(1) - self.safety.honda_rx_hook(self._gas_msg(1)) - self.assertFalse(self.safety.get_controls_allowed()) + for long_controls_allowed in [0, 1]: + self.safety.set_long_controls_allowed(long_controls_allowed) + self.safety.honda_rx_hook(self._gas_msg(0)) + self.safety.set_controls_allowed(1) + self.safety.honda_rx_hook(self._gas_msg(1)) + if long_controls_allowed: + self.assertFalse(self.safety.get_controls_allowed()) + else: + self.assertTrue(self.safety.get_controls_allowed()) + self.safety.set_long_controls_allowed(True) def test_allow_engage_with_gas_pressed(self): self.safety.honda_rx_hook(self._gas_msg(1)) @@ -148,18 +166,53 @@ class TestHondaSafety(unittest.TestCase): self.safety.honda_rx_hook(self._gas_msg(1)) self.assertTrue(self.safety.get_controls_allowed()) - def test_brake_safety_check(self): - self.assertTrue(self.safety.honda_tx_hook(self._send_brake_msg(0x0000))) - self.assertFalse(self.safety.honda_tx_hook(self._send_brake_msg(0x1000))) + def test_disengage_on_gas_interceptor(self): + for long_controls_allowed in [0, 1]: + self.safety.set_long_controls_allowed(long_controls_allowed) + self.safety.honda_rx_hook(self._send_interceptor_msg(0, 0x201)) + self.safety.set_controls_allowed(1) + self.safety.honda_rx_hook(self._send_interceptor_msg(0x1000, 0x201)) + if long_controls_allowed: + self.assertFalse(self.safety.get_controls_allowed()) + else: + self.assertTrue(self.safety.get_controls_allowed()) + self.safety.honda_rx_hook(self._send_interceptor_msg(0, 0x201)) + self.safety.set_gas_interceptor_detected(False) + self.safety.set_long_controls_allowed(True) + def test_allow_engage_with_gas_interceptor_pressed(self): + self.safety.honda_rx_hook(self._send_interceptor_msg(0x1000, 0x201)) self.safety.set_controls_allowed(1) - self.assertTrue(self.safety.honda_tx_hook(self._send_brake_msg(0x1000))) - self.assertFalse(self.safety.honda_tx_hook(self._send_brake_msg(0x00F0))) + self.safety.honda_rx_hook(self._send_interceptor_msg(0x1000, 0x201)) + self.assertTrue(self.safety.get_controls_allowed()) + self.safety.honda_rx_hook(self._send_interceptor_msg(0, 0x201)) + self.safety.set_gas_interceptor_detected(False) - def test_gas_safety_check(self): - self.safety.set_controls_allowed(0) - self.assertTrue(self.safety.honda_tx_hook(self._send_gas_msg(0x0000))) - self.assertFalse(self.safety.honda_tx_hook(self._send_gas_msg(0x1000))) + def test_brake_safety_check(self): + for long_controls_allowed in [0, 1]: + self.safety.set_long_controls_allowed(long_controls_allowed) + for brake in np.arange(0, MAX_BRAKE + 10, 1): + for controls_allowed in [True, False]: + self.safety.set_controls_allowed(controls_allowed) + if controls_allowed and long_controls_allowed: + send = MAX_BRAKE >= brake >= 0 + else: + send = brake == 0 + self.assertEqual(send, self.safety.honda_tx_hook(self._send_brake_msg(brake))) + self.safety.set_long_controls_allowed(True) + + def test_gas_interceptor_safety_check(self): + for long_controls_allowed in [0, 1]: + self.safety.set_long_controls_allowed(long_controls_allowed) + for gas in np.arange(0, 4000, 100): + for controls_allowed in [True, False]: + self.safety.set_controls_allowed(controls_allowed) + if controls_allowed and long_controls_allowed: + send = True + else: + send = gas == 0 + self.assertEqual(send, self.safety.honda_tx_hook(self._send_interceptor_msg(gas, 0x200))) + self.safety.set_long_controls_allowed(True) def test_steer_safety_check(self): self.safety.set_controls_allowed(0) @@ -171,7 +224,7 @@ class TestHondaSafety(unittest.TestCase): SET_BTN = 3 CANCEL_BTN = 2 BUTTON_MSG = 0x296 - self.safety.set_bosch_hardware(1) + self.safety.set_honda_bosch_hardware(1) self.safety.set_controls_allowed(0) self.assertTrue(self.safety.honda_tx_hook(self._button_msg(CANCEL_BTN, BUTTON_MSG))) self.assertFalse(self.safety.honda_tx_hook(self._button_msg(RESUME_BTN, BUTTON_MSG))) diff --git a/panda/tests/safety/test_toyota.py b/panda/tests/safety/test_toyota.py index 52c7015af..9badaec0f 100644 --- a/panda/tests/safety/test_toyota.py +++ b/panda/tests/safety/test_toyota.py @@ -119,13 +119,28 @@ class TestToyotaSafety(unittest.TestCase): to_send[0].RDLR = (a & 0xFF) << 8 | (a >> 8) return to_send - def _gas_msg(self, gas): + def _send_gas_msg(self, gas): to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') to_send[0].RIR = 0x200 << 21 to_send[0].RDLR = gas return to_send + def _send_interceptor_msg(self, gas, addr): + to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') + to_send[0].RIR = addr << 21 + to_send[0].RDTR = 6 + to_send[0].RDLR = ((gas & 0xff) << 8) | ((gas & 0xff00) >> 8) + + return to_send + + def _pcm_cruise_msg(self, cruise_on, gas_pressed): + to_send = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') + to_send[0].RIR = 0x1D2 << 21 + to_send[0].RDLR = (cruise_on << 5) | ((not gas_pressed) << 4 ) + + return to_send + def test_default_controls_not_allowed(self): self.assertFalse(self.safety.get_controls_allowed()) @@ -134,32 +149,84 @@ class TestToyotaSafety(unittest.TestCase): self.assertTrue(self.safety.get_controls_allowed()) def test_enable_control_allowed_from_cruise(self): - to_push = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') - to_push[0].RIR = 0x1D2 << 21 - to_push[0].RDLR = 0x20 - - self.safety.toyota_rx_hook(to_push) + self.safety.toyota_rx_hook(self._pcm_cruise_msg(False, False)) + self.assertFalse(self.safety.get_controls_allowed()) + self.safety.toyota_rx_hook(self._pcm_cruise_msg(True, False)) self.assertTrue(self.safety.get_controls_allowed()) def test_disable_control_allowed_from_cruise(self): - to_push = libpandasafety_py.ffi.new('CAN_FIFOMailBox_TypeDef *') - to_push[0].RIR = 0x1D2 << 21 - to_push[0].RDLR = 0 - self.safety.set_controls_allowed(1) - self.safety.toyota_rx_hook(to_push) + self.safety.toyota_rx_hook(self._pcm_cruise_msg(False, False)) self.assertFalse(self.safety.get_controls_allowed()) - def test_accel_actuation_limits(self): - for accel in np.arange(MIN_ACCEL - 1000, MAX_ACCEL + 1000, 100): - for controls_allowed in [True, False]: - self.safety.set_controls_allowed(controls_allowed) + def test_prev_gas(self): + self.safety.toyota_rx_hook(self._pcm_cruise_msg(False, False)) + self.assertFalse(self.safety.get_toyota_gas_prev()) + self.safety.toyota_rx_hook(self._pcm_cruise_msg(False, True)) + self.assertTrue(self.safety.get_toyota_gas_prev()) - if controls_allowed: - send = MIN_ACCEL <= accel <= MAX_ACCEL - else: - send = accel == 0 - self.assertEqual(send, self.safety.toyota_tx_hook(self._accel_msg(accel))) + def test_prev_gas_interceptor(self): + self.safety.toyota_rx_hook(self._send_interceptor_msg(0x0, 0x201)) + self.assertFalse(self.safety.get_gas_interceptor_prev()) + self.safety.toyota_rx_hook(self._send_interceptor_msg(0x1000, 0x201)) + self.assertTrue(self.safety.get_gas_interceptor_prev()) + self.safety.toyota_rx_hook(self._send_interceptor_msg(0x0, 0x201)) + self.safety.set_gas_interceptor_detected(False) + + def test_disengage_on_gas(self): + for long_controls_allowed in [0, 1]: + self.safety.set_long_controls_allowed(long_controls_allowed) + self.safety.toyota_rx_hook(self._pcm_cruise_msg(False, False)) + self.safety.toyota_rx_hook(self._pcm_cruise_msg(True, False)) + self.assertTrue(self.safety.get_controls_allowed()) + self.safety.toyota_rx_hook(self._pcm_cruise_msg(True, True)) + if long_controls_allowed: + self.assertFalse(self.safety.get_controls_allowed()) + else: + self.assertTrue(self.safety.get_controls_allowed()) + self.safety.set_long_controls_allowed(True) + + def test_allow_engage_with_gas_pressed(self): + self.safety.toyota_rx_hook(self._pcm_cruise_msg(False, True)) + self.safety.toyota_rx_hook(self._pcm_cruise_msg(True, True)) + self.assertTrue(self.safety.get_controls_allowed()) + self.safety.toyota_rx_hook(self._pcm_cruise_msg(True, True)) + self.assertTrue(self.safety.get_controls_allowed()) + + def test_disengage_on_gas_interceptor(self): + for long_controls_allowed in [0, 1]: + self.safety.set_long_controls_allowed(long_controls_allowed) + self.safety.toyota_rx_hook(self._send_interceptor_msg(0, 0x201)) + self.safety.set_controls_allowed(1) + self.safety.toyota_rx_hook(self._send_interceptor_msg(0x1000, 0x201)) + if long_controls_allowed: + self.assertFalse(self.safety.get_controls_allowed()) + else: + self.assertTrue(self.safety.get_controls_allowed()) + self.safety.toyota_rx_hook(self._send_interceptor_msg(0, 0x201)) + self.safety.set_gas_interceptor_detected(False) + self.safety.set_long_controls_allowed(True) + + def test_allow_engage_with_gas_interceptor_pressed(self): + self.safety.toyota_rx_hook(self._send_interceptor_msg(0x1000, 0x201)) + self.safety.set_controls_allowed(1) + self.safety.toyota_rx_hook(self._send_interceptor_msg(0x1000, 0x201)) + self.assertTrue(self.safety.get_controls_allowed()) + self.safety.toyota_rx_hook(self._send_interceptor_msg(0, 0x201)) + self.safety.set_gas_interceptor_detected(False) + + def test_accel_actuation_limits(self): + for long_controls_allowed in [0, 1]: + self.safety.set_long_controls_allowed(long_controls_allowed) + for accel in np.arange(MIN_ACCEL - 1000, MAX_ACCEL + 1000, 100): + for controls_allowed in [True, False]: + self.safety.set_controls_allowed(controls_allowed) + if controls_allowed and long_controls_allowed: + send = MIN_ACCEL <= accel <= MAX_ACCEL + else: + send = accel == 0 + self.assertEqual(send, self.safety.toyota_tx_hook(self._accel_msg(accel))) + self.safety.set_long_controls_allowed(True) def test_torque_absolute_limits(self): for controls_allowed in [True, False]: @@ -244,11 +311,11 @@ class TestToyotaSafety(unittest.TestCase): self.assertEqual(51, self.safety.get_toyota_torque_meas_max()) self.safety.toyota_rx_hook(self._torque_meas_msg(0)) - self.assertEqual(-1, self.safety.get_toyota_torque_meas_max()) + self.assertEqual(1, self.safety.get_toyota_torque_meas_max()) self.assertEqual(-51, self.safety.get_toyota_torque_meas_min()) self.safety.toyota_rx_hook(self._torque_meas_msg(0)) - self.assertEqual(-1, self.safety.get_toyota_torque_meas_max()) + self.assertEqual(1, self.safety.get_toyota_torque_meas_max()) self.assertEqual(-1, self.safety.get_toyota_torque_meas_min()) def test_ipas_override(self): @@ -416,12 +483,13 @@ class TestToyotaSafety(unittest.TestCase): # reset no angle control at the end of the test self.safety.reset_angle_control() - def test_gas_safety_check(self): + def test_gas_interceptor_safety_check(self): + self.safety.set_controls_allowed(0) - self.assertTrue(self.safety.honda_tx_hook(self._gas_msg(0x0000))) - self.assertFalse(self.safety.honda_tx_hook(self._gas_msg(0x1000))) + self.assertTrue(self.safety.toyota_tx_hook(self._send_interceptor_msg(0, 0x200))) + self.assertFalse(self.safety.toyota_tx_hook(self._send_interceptor_msg(0x1000, 0x200))) self.safety.set_controls_allowed(1) - self.assertTrue(self.safety.honda_tx_hook(self._gas_msg(0x1000))) + self.assertTrue(self.safety.toyota_tx_hook(self._send_interceptor_msg(0x1000, 0x200))) if __name__ == "__main__": diff --git a/pyextra/PyJWT-1.4.1-py2.7.egg-info/PKG-INFO b/pyextra/PyJWT-1.4.1-py2.7.egg-info/PKG-INFO new file mode 100644 index 000000000..91af37c9f --- /dev/null +++ b/pyextra/PyJWT-1.4.1-py2.7.egg-info/PKG-INFO @@ -0,0 +1,70 @@ +Metadata-Version: 1.1 +Name: PyJWT +Version: 1.4.1 +Summary: JSON Web Token implementation in Python +Home-page: http://github.com/jpadilla/pyjwt +Author: José Padilla +Author-email: hello@jpadilla.com +License: MIT +Description: # PyJWT + + [![travis-status-image]][travis] + [![appveyor-status-image]][appveyor] + [![pypi-version-image]][pypi] + [![coveralls-status-image]][coveralls] + [![docs-status-image]][docs] + + A Python implementation of [RFC 7519][jwt-spec]. + Original implementation was written by [@progrium][progrium]. + + ## Installing + + ``` + $ pip install PyJWT + ``` + + ## Usage + + ```python + >>> import jwt + >>> encoded = jwt.encode({'some': 'payload'}, 'secret', algorithm='HS256') + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzb21lIjoicGF5bG9hZCJ9.4twFt5NiznN84AWoo1d7KO1T_yoc0Z6XOpOVswacPZg' + + >>> jwt.decode(encoded, 'secret', algorithms=['HS256']) + {'some': 'payload'} + ``` + + ## Tests + + You can run tests from the project root after cloning with: + + ``` + $ python setup.py test + ``` + + [travis-status-image]: https://secure.travis-ci.org/jpadilla/pyjwt.svg?branch=master + [travis]: http://travis-ci.org/jpadilla/pyjwt?branch=master + [appveyor-status-image]: https://ci.appveyor.com/api/projects/status/h8nt70aqtwhht39t?svg=true + [appveyor]: https://ci.appveyor.com/project/jpadilla/pyjwt + [pypi-version-image]: https://img.shields.io/pypi/v/pyjwt.svg + [pypi]: https://pypi.python.org/pypi/pyjwt + [coveralls-status-image]: https://coveralls.io/repos/jpadilla/pyjwt/badge.svg?branch=master + [coveralls]: https://coveralls.io/r/jpadilla/pyjwt?branch=master + [docs-status-image]: https://readthedocs.org/projects/pyjwt/badge/?version=latest + [docs]: http://pyjwt.readthedocs.org + [jwt-spec]: https://tools.ietf.org/html/rfc7519 + [progrium]: https://github.com/progrium + +Keywords: jwt json web token security signing +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Natural Language :: English +Classifier: License :: OSI Approved :: MIT License +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Topic :: Utilities diff --git a/pyextra/PyJWT-1.4.1-py2.7.egg-info/SOURCES.txt b/pyextra/PyJWT-1.4.1-py2.7.egg-info/SOURCES.txt new file mode 100644 index 000000000..972fb0f8a --- /dev/null +++ b/pyextra/PyJWT-1.4.1-py2.7.egg-info/SOURCES.txt @@ -0,0 +1,49 @@ +AUTHORS +CHANGELOG.md +LICENSE +MANIFEST.in +README.md +setup.cfg +setup.py +tox.ini +PyJWT.egg-info/PKG-INFO +PyJWT.egg-info/SOURCES.txt +PyJWT.egg-info/dependency_links.txt +PyJWT.egg-info/entry_points.txt +PyJWT.egg-info/requires.txt +PyJWT.egg-info/top_level.txt +jwt/__init__.py +jwt/__main__.py +jwt/algorithms.py +jwt/api_jws.py +jwt/api_jwt.py +jwt/compat.py +jwt/exceptions.py +jwt/utils.py +jwt/contrib/__init__.py +jwt/contrib/algorithms/__init__.py +jwt/contrib/algorithms/py_ecdsa.py +jwt/contrib/algorithms/pycrypto.py +tests/__init__.py +tests/compat.py +tests/test_algorithms.py +tests/test_api_jws.py +tests/test_api_jwt.py +tests/test_compat.py +tests/test_exceptions.py +tests/test_jwt.py +tests/utils.py +tests/contrib/__init__.py +tests/contrib/test_algorithms.py +tests/keys/__init__.py +tests/keys/jwk_ec_key.json +tests/keys/jwk_ec_pub.json +tests/keys/jwk_hmac.json +tests/keys/jwk_rsa_key.json +tests/keys/jwk_rsa_pub.json +tests/keys/testkey2_rsa.pub.pem +tests/keys/testkey_ec +tests/keys/testkey_ec.pub +tests/keys/testkey_rsa +tests/keys/testkey_rsa.cer +tests/keys/testkey_rsa.pub \ No newline at end of file diff --git a/pyextra/PyJWT-1.4.1-py2.7.egg-info/dependency_links.txt b/pyextra/PyJWT-1.4.1-py2.7.egg-info/dependency_links.txt new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/pyextra/PyJWT-1.4.1-py2.7.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/pyextra/PyJWT-1.4.1-py2.7.egg-info/entry_points.txt b/pyextra/PyJWT-1.4.1-py2.7.egg-info/entry_points.txt new file mode 100644 index 000000000..cbdf40f14 --- /dev/null +++ b/pyextra/PyJWT-1.4.1-py2.7.egg-info/entry_points.txt @@ -0,0 +1,3 @@ +[console_scripts] +jwt = jwt.__main__:main + diff --git a/pyextra/PyJWT-1.4.1-py2.7.egg-info/installed-files.txt b/pyextra/PyJWT-1.4.1-py2.7.egg-info/installed-files.txt new file mode 100644 index 000000000..d3e93ab1d --- /dev/null +++ b/pyextra/PyJWT-1.4.1-py2.7.egg-info/installed-files.txt @@ -0,0 +1,31 @@ +../../../../bin/jwt +../jwt/__init__.py +../jwt/__init__.pyc +../jwt/__main__.py +../jwt/__main__.pyc +../jwt/algorithms.py +../jwt/algorithms.pyc +../jwt/api_jws.py +../jwt/api_jws.pyc +../jwt/api_jwt.py +../jwt/api_jwt.pyc +../jwt/compat.py +../jwt/compat.pyc +../jwt/contrib/__init__.py +../jwt/contrib/__init__.pyc +../jwt/contrib/algorithms/__init__.py +../jwt/contrib/algorithms/__init__.pyc +../jwt/contrib/algorithms/py_ecdsa.py +../jwt/contrib/algorithms/py_ecdsa.pyc +../jwt/contrib/algorithms/pycrypto.py +../jwt/contrib/algorithms/pycrypto.pyc +../jwt/exceptions.py +../jwt/exceptions.pyc +../jwt/utils.py +../jwt/utils.pyc +PKG-INFO +SOURCES.txt +dependency_links.txt +entry_points.txt +requires.txt +top_level.txt diff --git a/pyextra/PyJWT-1.4.1-py2.7.egg-info/requires.txt b/pyextra/PyJWT-1.4.1-py2.7.egg-info/requires.txt new file mode 100644 index 000000000..67cccf541 --- /dev/null +++ b/pyextra/PyJWT-1.4.1-py2.7.egg-info/requires.txt @@ -0,0 +1,13 @@ + +[crypto] +cryptography + +[flake8] +flake8 +flake8-import-order +pep8-naming + +[test] +pytest==2.7.3 +pytest-cov +pytest-runner diff --git a/pyextra/PyJWT-1.4.1-py2.7.egg-info/top_level.txt b/pyextra/PyJWT-1.4.1-py2.7.egg-info/top_level.txt new file mode 100644 index 000000000..27ccc9bc3 --- /dev/null +++ b/pyextra/PyJWT-1.4.1-py2.7.egg-info/top_level.txt @@ -0,0 +1 @@ +jwt diff --git a/pyextra/jwt/__init__.py b/pyextra/jwt/__init__.py new file mode 100644 index 000000000..d70cdf056 --- /dev/null +++ b/pyextra/jwt/__init__.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# flake8: noqa + +""" +JSON Web Token implementation + +Minimum implementation based on this spec: +http://self-issued.info/docs/draft-jones-json-web-token-01.html +""" + + +__title__ = 'pyjwt' +__version__ = '1.4.1' +__author__ = 'José Padilla' +__license__ = 'MIT' +__copyright__ = 'Copyright 2015 José Padilla' + + +from .api_jwt import ( + encode, decode, register_algorithm, unregister_algorithm, + get_unverified_header, PyJWT +) +from .api_jws import PyJWS +from .exceptions import ( + InvalidTokenError, DecodeError, InvalidAudienceError, + ExpiredSignatureError, ImmatureSignatureError, InvalidIssuedAtError, + InvalidIssuerError, ExpiredSignature, InvalidAudience, InvalidIssuer, + MissingRequiredClaimError +) diff --git a/pyextra/jwt/__main__.py b/pyextra/jwt/__main__.py new file mode 100644 index 000000000..fffe21230 --- /dev/null +++ b/pyextra/jwt/__main__.py @@ -0,0 +1,135 @@ +#!/usr/bin/env python + +from __future__ import absolute_import, print_function + +import json +import optparse +import sys +import time + +from . import DecodeError, __package__, __version__, decode, encode + + +def main(): + + usage = '''Encodes or decodes JSON Web Tokens based on input. + + %prog [options] input + +Decoding examples: + + %prog --key=secret json.web.token + %prog --no-verify json.web.token + +Encoding requires the key option and takes space separated key/value pairs +separated by equals (=) as input. Examples: + + %prog --key=secret iss=me exp=1302049071 + %prog --key=secret foo=bar exp=+10 + +The exp key is special and can take an offset to current Unix time.\ +''' + p = optparse.OptionParser( + usage=usage, + prog=__package__, + version='%s %s' % (__package__, __version__), + ) + + p.add_option( + '-n', '--no-verify', + action='store_false', + dest='verify', + default=True, + help='ignore signature and claims verification on decode' + ) + + p.add_option( + '--key', + dest='key', + metavar='KEY', + default=None, + help='set the secret key to sign with' + ) + + p.add_option( + '--alg', + dest='algorithm', + metavar='ALG', + default='HS256', + help='set crypto algorithm to sign with. default=HS256' + ) + + options, arguments = p.parse_args() + + if len(arguments) > 0 or not sys.stdin.isatty(): + if len(arguments) == 1 and (not options.verify or options.key): + # Try to decode + try: + if not sys.stdin.isatty(): + token = sys.stdin.read() + else: + token = arguments[0] + + token = token.encode('utf-8') + data = decode(token, key=options.key, verify=options.verify) + + print(json.dumps(data)) + sys.exit(0) + except DecodeError as e: + print(e) + sys.exit(1) + + # Try to encode + if options.key is None: + print('Key is required when encoding. See --help for usage.') + sys.exit(1) + + # Build payload object to encode + payload = {} + + for arg in arguments: + try: + k, v = arg.split('=', 1) + + # exp +offset special case? + if k == 'exp' and v[0] == '+' and len(v) > 1: + v = str(int(time.time()+int(v[1:]))) + + # Cast to integer? + if v.isdigit(): + v = int(v) + else: + # Cast to float? + try: + v = float(v) + except ValueError: + pass + + # Cast to true, false, or null? + constants = {'true': True, 'false': False, 'null': None} + + if v in constants: + v = constants[v] + + payload[k] = v + except ValueError: + print('Invalid encoding input at {}'.format(arg)) + sys.exit(1) + + try: + token = encode( + payload, + key=options.key, + algorithm=options.algorithm + ) + + print(token) + sys.exit(0) + except Exception as e: + print(e) + sys.exit(1) + else: + p.print_help() + +if __name__ == '__main__': + main() diff --git a/pyextra/jwt/algorithms.py b/pyextra/jwt/algorithms.py new file mode 100644 index 000000000..9c1a7e803 --- /dev/null +++ b/pyextra/jwt/algorithms.py @@ -0,0 +1,290 @@ +import hashlib +import hmac + +from .compat import constant_time_compare, string_types, text_type +from .exceptions import InvalidKeyError +from .utils import der_to_raw_signature, raw_to_der_signature + +try: + from cryptography.hazmat.primitives import hashes + from cryptography.hazmat.primitives.serialization import ( + load_pem_private_key, load_pem_public_key, load_ssh_public_key + ) + from cryptography.hazmat.primitives.asymmetric.rsa import ( + RSAPrivateKey, RSAPublicKey + ) + from cryptography.hazmat.primitives.asymmetric.ec import ( + EllipticCurvePrivateKey, EllipticCurvePublicKey + ) + from cryptography.hazmat.primitives.asymmetric import ec, padding + from cryptography.hazmat.backends import default_backend + from cryptography.exceptions import InvalidSignature + + has_crypto = True +except ImportError: + has_crypto = False + + +def get_default_algorithms(): + """ + Returns the algorithms that are implemented by the library. + """ + default_algorithms = { + 'none': NoneAlgorithm(), + 'HS256': HMACAlgorithm(HMACAlgorithm.SHA256), + 'HS384': HMACAlgorithm(HMACAlgorithm.SHA384), + 'HS512': HMACAlgorithm(HMACAlgorithm.SHA512) + } + + if has_crypto: + default_algorithms.update({ + 'RS256': RSAAlgorithm(RSAAlgorithm.SHA256), + 'RS384': RSAAlgorithm(RSAAlgorithm.SHA384), + 'RS512': RSAAlgorithm(RSAAlgorithm.SHA512), + 'ES256': ECAlgorithm(ECAlgorithm.SHA256), + 'ES384': ECAlgorithm(ECAlgorithm.SHA384), + 'ES512': ECAlgorithm(ECAlgorithm.SHA512), + 'PS256': RSAPSSAlgorithm(RSAPSSAlgorithm.SHA256), + 'PS384': RSAPSSAlgorithm(RSAPSSAlgorithm.SHA384), + 'PS512': RSAPSSAlgorithm(RSAPSSAlgorithm.SHA512) + }) + + return default_algorithms + + +class Algorithm(object): + """ + The interface for an algorithm used to sign and verify tokens. + """ + def prepare_key(self, key): + """ + Performs necessary validation and conversions on the key and returns + the key value in the proper format for sign() and verify(). + """ + raise NotImplementedError + + def sign(self, msg, key): + """ + Returns a digital signature for the specified message + using the specified key value. + """ + raise NotImplementedError + + def verify(self, msg, key, sig): + """ + Verifies that the specified digital signature is valid + for the specified message and key values. + """ + raise NotImplementedError + + +class NoneAlgorithm(Algorithm): + """ + Placeholder for use when no signing or verification + operations are required. + """ + def prepare_key(self, key): + if key == '': + key = None + + if key is not None: + raise InvalidKeyError('When alg = "none", key value must be None.') + + return key + + def sign(self, msg, key): + return b'' + + def verify(self, msg, key, sig): + return False + + +class HMACAlgorithm(Algorithm): + """ + Performs signing and verification operations using HMAC + and the specified hash function. + """ + SHA256 = hashlib.sha256 + SHA384 = hashlib.sha384 + SHA512 = hashlib.sha512 + + def __init__(self, hash_alg): + self.hash_alg = hash_alg + + def prepare_key(self, key): + if not isinstance(key, string_types) and not isinstance(key, bytes): + raise TypeError('Expecting a string- or bytes-formatted key.') + + if isinstance(key, text_type): + key = key.encode('utf-8') + + invalid_strings = [ + b'-----BEGIN PUBLIC KEY-----', + b'-----BEGIN CERTIFICATE-----', + b'ssh-rsa' + ] + + if any([string_value in key for string_value in invalid_strings]): + raise InvalidKeyError( + 'The specified key is an asymmetric key or x509 certificate and' + ' should not be used as an HMAC secret.') + + return key + + def sign(self, msg, key): + return hmac.new(key, msg, self.hash_alg).digest() + + def verify(self, msg, key, sig): + return constant_time_compare(sig, self.sign(msg, key)) + +if has_crypto: + + class RSAAlgorithm(Algorithm): + """ + Performs signing and verification operations using + RSASSA-PKCS-v1_5 and the specified hash function. + """ + SHA256 = hashes.SHA256 + SHA384 = hashes.SHA384 + SHA512 = hashes.SHA512 + + def __init__(self, hash_alg): + self.hash_alg = hash_alg + + def prepare_key(self, key): + if isinstance(key, RSAPrivateKey) or \ + isinstance(key, RSAPublicKey): + return key + + if isinstance(key, string_types): + if isinstance(key, text_type): + key = key.encode('utf-8') + + try: + if key.startswith(b'ssh-rsa'): + key = load_ssh_public_key(key, backend=default_backend()) + else: + key = load_pem_private_key(key, password=None, backend=default_backend()) + except ValueError: + key = load_pem_public_key(key, backend=default_backend()) + else: + raise TypeError('Expecting a PEM-formatted key.') + + return key + + def sign(self, msg, key): + signer = key.signer( + padding.PKCS1v15(), + self.hash_alg() + ) + + signer.update(msg) + return signer.finalize() + + def verify(self, msg, key, sig): + verifier = key.verifier( + sig, + padding.PKCS1v15(), + self.hash_alg() + ) + + verifier.update(msg) + + try: + verifier.verify() + return True + except InvalidSignature: + return False + + class ECAlgorithm(Algorithm): + """ + Performs signing and verification operations using + ECDSA and the specified hash function + """ + SHA256 = hashes.SHA256 + SHA384 = hashes.SHA384 + SHA512 = hashes.SHA512 + + def __init__(self, hash_alg): + self.hash_alg = hash_alg + + def prepare_key(self, key): + if isinstance(key, EllipticCurvePrivateKey) or \ + isinstance(key, EllipticCurvePublicKey): + return key + + if isinstance(key, string_types): + if isinstance(key, text_type): + key = key.encode('utf-8') + + # Attempt to load key. We don't know if it's + # a Signing Key or a Verifying Key, so we try + # the Verifying Key first. + try: + key = load_pem_public_key(key, backend=default_backend()) + except ValueError: + key = load_pem_private_key(key, password=None, backend=default_backend()) + + else: + raise TypeError('Expecting a PEM-formatted key.') + + return key + + def sign(self, msg, key): + signer = key.signer(ec.ECDSA(self.hash_alg())) + + signer.update(msg) + der_sig = signer.finalize() + + return der_to_raw_signature(der_sig, key.curve) + + def verify(self, msg, key, sig): + try: + der_sig = raw_to_der_signature(sig, key.curve) + except ValueError: + return False + + verifier = key.verifier(der_sig, ec.ECDSA(self.hash_alg())) + + verifier.update(msg) + + try: + verifier.verify() + return True + except InvalidSignature: + return False + + class RSAPSSAlgorithm(RSAAlgorithm): + """ + Performs a signature using RSASSA-PSS with MGF1 + """ + + def sign(self, msg, key): + signer = key.signer( + padding.PSS( + mgf=padding.MGF1(self.hash_alg()), + salt_length=self.hash_alg.digest_size + ), + self.hash_alg() + ) + + signer.update(msg) + return signer.finalize() + + def verify(self, msg, key, sig): + verifier = key.verifier( + sig, + padding.PSS( + mgf=padding.MGF1(self.hash_alg()), + salt_length=self.hash_alg.digest_size + ), + self.hash_alg() + ) + + verifier.update(msg) + + try: + verifier.verify() + return True + except InvalidSignature: + return False diff --git a/pyextra/jwt/api_jws.py b/pyextra/jwt/api_jws.py new file mode 100644 index 000000000..177f5ff55 --- /dev/null +++ b/pyextra/jwt/api_jws.py @@ -0,0 +1,204 @@ +import binascii +import json +import warnings + +from collections import Mapping + +from .algorithms import Algorithm, get_default_algorithms # NOQA +from .compat import binary_type, string_types, text_type +from .exceptions import DecodeError, InvalidAlgorithmError, InvalidTokenError +from .utils import base64url_decode, base64url_encode, merge_dict + + +class PyJWS(object): + header_typ = 'JWT' + + def __init__(self, algorithms=None, options=None): + self._algorithms = get_default_algorithms() + self._valid_algs = (set(algorithms) if algorithms is not None + else set(self._algorithms)) + + # Remove algorithms that aren't on the whitelist + for key in list(self._algorithms.keys()): + if key not in self._valid_algs: + del self._algorithms[key] + + if not options: + options = {} + + self.options = merge_dict(self._get_default_options(), options) + + @staticmethod + def _get_default_options(): + return { + 'verify_signature': True + } + + def register_algorithm(self, alg_id, alg_obj): + """ + Registers a new Algorithm for use when creating and verifying tokens. + """ + if alg_id in self._algorithms: + raise ValueError('Algorithm already has a handler.') + + if not isinstance(alg_obj, Algorithm): + raise TypeError('Object is not of type `Algorithm`') + + self._algorithms[alg_id] = alg_obj + self._valid_algs.add(alg_id) + + def unregister_algorithm(self, alg_id): + """ + Unregisters an Algorithm for use when creating and verifying tokens + Throws KeyError if algorithm is not registered. + """ + if alg_id not in self._algorithms: + raise KeyError('The specified algorithm could not be removed' + ' because it is not registered.') + + del self._algorithms[alg_id] + self._valid_algs.remove(alg_id) + + def get_algorithms(self): + """ + Returns a list of supported values for the 'alg' parameter. + """ + return list(self._valid_algs) + + def encode(self, payload, key, algorithm='HS256', headers=None, + json_encoder=None): + segments = [] + + if algorithm is None: + algorithm = 'none' + + if algorithm not in self._valid_algs: + pass + + # Header + header = {'typ': self.header_typ, 'alg': algorithm} + + if headers: + self._validate_headers(headers) + header.update(headers) + + json_header = json.dumps( + header, + separators=(',', ':'), + cls=json_encoder + ).encode('utf-8') + + segments.append(base64url_encode(json_header)) + segments.append(base64url_encode(payload)) + + # Segments + signing_input = b'.'.join(segments) + try: + alg_obj = self._algorithms[algorithm] + key = alg_obj.prepare_key(key) + signature = alg_obj.sign(signing_input, key) + + except KeyError: + raise NotImplementedError('Algorithm not supported') + + segments.append(base64url_encode(signature)) + + return b'.'.join(segments) + + def decode(self, jws, key='', verify=True, algorithms=None, options=None, + **kwargs): + payload, signing_input, header, signature = self._load(jws) + + if verify: + merged_options = merge_dict(self.options, options) + if merged_options.get('verify_signature'): + self._verify_signature(payload, signing_input, header, signature, + key, algorithms) + else: + warnings.warn('The verify parameter is deprecated. ' + 'Please use options instead.', DeprecationWarning) + + return payload + + def get_unverified_header(self, jwt): + """Returns back the JWT header parameters as a dict() + + Note: The signature is not verified so the header parameters + should not be fully trusted until signature verification is complete + """ + headers = self._load(jwt)[2] + self._validate_headers(headers) + + return headers + + def _load(self, jwt): + if isinstance(jwt, text_type): + jwt = jwt.encode('utf-8') + + if not issubclass(type(jwt), binary_type): + raise DecodeError("Invalid token type. Token must be a {0}".format( + binary_type)) + + try: + signing_input, crypto_segment = jwt.rsplit(b'.', 1) + header_segment, payload_segment = signing_input.split(b'.', 1) + except ValueError: + raise DecodeError('Not enough segments') + + try: + header_data = base64url_decode(header_segment) + except (TypeError, binascii.Error): + raise DecodeError('Invalid header padding') + + try: + header = json.loads(header_data.decode('utf-8')) + except ValueError as e: + raise DecodeError('Invalid header string: %s' % e) + + if not isinstance(header, Mapping): + raise DecodeError('Invalid header string: must be a json object') + + try: + payload = base64url_decode(payload_segment) + except (TypeError, binascii.Error): + raise DecodeError('Invalid payload padding') + + try: + signature = base64url_decode(crypto_segment) + except (TypeError, binascii.Error): + raise DecodeError('Invalid crypto padding') + + return (payload, signing_input, header, signature) + + def _verify_signature(self, payload, signing_input, header, signature, + key='', algorithms=None): + + alg = header.get('alg') + + if algorithms is not None and alg not in algorithms: + raise InvalidAlgorithmError('The specified alg value is not allowed') + + try: + alg_obj = self._algorithms[alg] + key = alg_obj.prepare_key(key) + + if not alg_obj.verify(signing_input, key, signature): + raise DecodeError('Signature verification failed') + + except KeyError: + raise InvalidAlgorithmError('Algorithm not supported') + + def _validate_headers(self, headers): + if 'kid' in headers: + self._validate_kid(headers['kid']) + + def _validate_kid(self, kid): + if not isinstance(kid, string_types): + raise InvalidTokenError('Key ID header parameter must be a string') + +_jws_global_obj = PyJWS() +encode = _jws_global_obj.encode +decode = _jws_global_obj.decode +register_algorithm = _jws_global_obj.register_algorithm +unregister_algorithm = _jws_global_obj.unregister_algorithm +get_unverified_header = _jws_global_obj.get_unverified_header diff --git a/pyextra/jwt/api_jwt.py b/pyextra/jwt/api_jwt.py new file mode 100644 index 000000000..9703b8d6c --- /dev/null +++ b/pyextra/jwt/api_jwt.py @@ -0,0 +1,187 @@ +import json +import warnings + +from calendar import timegm +from collections import Mapping +from datetime import datetime, timedelta + +from .api_jws import PyJWS +from .algorithms import Algorithm, get_default_algorithms # NOQA +from .compat import string_types, timedelta_total_seconds +from .exceptions import ( + DecodeError, ExpiredSignatureError, ImmatureSignatureError, + InvalidAudienceError, InvalidIssuedAtError, + InvalidIssuerError, MissingRequiredClaimError +) +from .utils import merge_dict + + +class PyJWT(PyJWS): + header_type = 'JWT' + + @staticmethod + def _get_default_options(): + return { + 'verify_signature': True, + 'verify_exp': True, + 'verify_nbf': True, + 'verify_iat': True, + 'verify_aud': True, + 'verify_iss': True, + 'require_exp': False, + 'require_iat': False, + 'require_nbf': False + } + + def encode(self, payload, key, algorithm='HS256', headers=None, + json_encoder=None): + # Check that we get a mapping + if not isinstance(payload, Mapping): + raise TypeError('Expecting a mapping object, as JWT only supports ' + 'JSON objects as payloads.') + + # Payload + for time_claim in ['exp', 'iat', 'nbf']: + # Convert datetime to a intDate value in known time-format claims + if isinstance(payload.get(time_claim), datetime): + payload[time_claim] = timegm(payload[time_claim].utctimetuple()) + + json_payload = json.dumps( + payload, + separators=(',', ':'), + cls=json_encoder + ).encode('utf-8') + + return super(PyJWT, self).encode( + json_payload, key, algorithm, headers, json_encoder + ) + + def decode(self, jwt, key='', verify=True, algorithms=None, options=None, + **kwargs): + payload, signing_input, header, signature = self._load(jwt) + + decoded = super(PyJWT, self).decode(jwt, key, verify, algorithms, + options, **kwargs) + + try: + payload = json.loads(decoded.decode('utf-8')) + except ValueError as e: + raise DecodeError('Invalid payload string: %s' % e) + if not isinstance(payload, Mapping): + raise DecodeError('Invalid payload string: must be a json object') + + if verify: + merged_options = merge_dict(self.options, options) + self._validate_claims(payload, merged_options, **kwargs) + + return payload + + def _validate_claims(self, payload, options, audience=None, issuer=None, + leeway=0, **kwargs): + + if 'verify_expiration' in kwargs: + options['verify_exp'] = kwargs.get('verify_expiration', True) + warnings.warn('The verify_expiration parameter is deprecated. ' + 'Please use options instead.', DeprecationWarning) + + if isinstance(leeway, timedelta): + leeway = timedelta_total_seconds(leeway) + + if not isinstance(audience, (string_types, type(None))): + raise TypeError('audience must be a string or None') + + self._validate_required_claims(payload, options) + + now = timegm(datetime.utcnow().utctimetuple()) + + if 'iat' in payload and options.get('verify_iat'): + self._validate_iat(payload, now, leeway) + + if 'nbf' in payload and options.get('verify_nbf'): + self._validate_nbf(payload, now, leeway) + + if 'exp' in payload and options.get('verify_exp'): + self._validate_exp(payload, now, leeway) + + if options.get('verify_iss'): + self._validate_iss(payload, issuer) + + if options.get('verify_aud'): + self._validate_aud(payload, audience) + + def _validate_required_claims(self, payload, options): + if options.get('require_exp') and payload.get('exp') is None: + raise MissingRequiredClaimError('exp') + + if options.get('require_iat') and payload.get('iat') is None: + raise MissingRequiredClaimError('iat') + + if options.get('require_nbf') and payload.get('nbf') is None: + raise MissingRequiredClaimError('nbf') + + def _validate_iat(self, payload, now, leeway): + try: + iat = int(payload['iat']) + except ValueError: + raise DecodeError('Issued At claim (iat) must be an integer.') + + if iat > (now + leeway): + raise InvalidIssuedAtError('Issued At claim (iat) cannot be in' + ' the future.') + + def _validate_nbf(self, payload, now, leeway): + try: + nbf = int(payload['nbf']) + except ValueError: + raise DecodeError('Not Before claim (nbf) must be an integer.') + + if nbf > (now + leeway): + raise ImmatureSignatureError('The token is not yet valid (nbf)') + + def _validate_exp(self, payload, now, leeway): + try: + exp = int(payload['exp']) + except ValueError: + raise DecodeError('Expiration Time claim (exp) must be an' + ' integer.') + + if exp < (now - leeway): + raise ExpiredSignatureError('Signature has expired') + + def _validate_aud(self, payload, audience): + if audience is None and 'aud' not in payload: + return + + if audience is not None and 'aud' not in payload: + # Application specified an audience, but it could not be + # verified since the token does not contain a claim. + raise MissingRequiredClaimError('aud') + + audience_claims = payload['aud'] + + if isinstance(audience_claims, string_types): + audience_claims = [audience_claims] + if not isinstance(audience_claims, list): + raise InvalidAudienceError('Invalid claim format in token') + if any(not isinstance(c, string_types) for c in audience_claims): + raise InvalidAudienceError('Invalid claim format in token') + if audience not in audience_claims: + raise InvalidAudienceError('Invalid audience') + + def _validate_iss(self, payload, issuer): + if issuer is None: + return + + if 'iss' not in payload: + raise MissingRequiredClaimError('iss') + + if payload['iss'] != issuer: + raise InvalidIssuerError('Invalid issuer') + + +_jwt_global_obj = PyJWT() +encode = _jwt_global_obj.encode +decode = _jwt_global_obj.decode +register_algorithm = _jwt_global_obj.register_algorithm +unregister_algorithm = _jwt_global_obj.unregister_algorithm +get_unverified_header = _jwt_global_obj.get_unverified_header diff --git a/pyextra/jwt/compat.py b/pyextra/jwt/compat.py new file mode 100644 index 000000000..8f6bfed14 --- /dev/null +++ b/pyextra/jwt/compat.py @@ -0,0 +1,54 @@ +""" +The `compat` module provides support for backwards compatibility with older +versions of python, and compatibility wrappers around optional packages. +""" +# flake8: noqa +import sys +import hmac + + +PY3 = sys.version_info[0] == 3 + + +if PY3: + string_types = str, + text_type = str + binary_type = bytes +else: + string_types = basestring, + text_type = unicode + binary_type = str + + +def timedelta_total_seconds(delta): + try: + delta.total_seconds + except AttributeError: + # On Python 2.6, timedelta instances do not have + # a .total_seconds() method. + total_seconds = delta.days * 24 * 60 * 60 + delta.seconds + else: + total_seconds = delta.total_seconds() + + return total_seconds + + +try: + constant_time_compare = hmac.compare_digest +except AttributeError: + # Fallback for Python < 2.7 + def constant_time_compare(val1, val2): + """ + Returns True if the two strings are equal, False otherwise. + + The time taken is independent of the number of characters that match. + """ + if len(val1) != len(val2): + return False + + result = 0 + + for x, y in zip(val1, val2): + result |= ord(x) ^ ord(y) + + return result == 0 diff --git a/selfdrive/mapd/__init__.py b/pyextra/jwt/contrib/__init__.py similarity index 100% rename from selfdrive/mapd/__init__.py rename to pyextra/jwt/contrib/__init__.py diff --git a/pyextra/jwt/contrib/algorithms/__init__.py b/pyextra/jwt/contrib/algorithms/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/pyextra/jwt/contrib/algorithms/py_ecdsa.py b/pyextra/jwt/contrib/algorithms/py_ecdsa.py new file mode 100644 index 000000000..bf0dea5ae --- /dev/null +++ b/pyextra/jwt/contrib/algorithms/py_ecdsa.py @@ -0,0 +1,60 @@ +# Note: This file is named py_ecdsa.py because import behavior in Python 2 +# would cause ecdsa.py to squash the ecdsa library that it depends upon. + +import hashlib + +import ecdsa + +from jwt.algorithms import Algorithm +from jwt.compat import string_types, text_type + + +class ECAlgorithm(Algorithm): + """ + Performs signing and verification operations using + ECDSA and the specified hash function + + This class requires the ecdsa package to be installed. + + This is based off of the implementation in PyJWT 0.3.2 + """ + SHA256 = hashlib.sha256 + SHA384 = hashlib.sha384 + SHA512 = hashlib.sha512 + + def __init__(self, hash_alg): + self.hash_alg = hash_alg + + def prepare_key(self, key): + + if isinstance(key, ecdsa.SigningKey) or \ + isinstance(key, ecdsa.VerifyingKey): + return key + + if isinstance(key, string_types): + if isinstance(key, text_type): + key = key.encode('utf-8') + + # Attempt to load key. We don't know if it's + # a Signing Key or a Verifying Key, so we try + # the Verifying Key first. + try: + key = ecdsa.VerifyingKey.from_pem(key) + except ecdsa.der.UnexpectedDER: + key = ecdsa.SigningKey.from_pem(key) + + else: + raise TypeError('Expecting a PEM-formatted key.') + + return key + + def sign(self, msg, key): + return key.sign(msg, hashfunc=self.hash_alg, + sigencode=ecdsa.util.sigencode_string) + + def verify(self, msg, key, sig): + try: + return key.verify(sig, msg, hashfunc=self.hash_alg, + sigdecode=ecdsa.util.sigdecode_string) + except AssertionError: + return False diff --git a/pyextra/jwt/contrib/algorithms/pycrypto.py b/pyextra/jwt/contrib/algorithms/pycrypto.py new file mode 100644 index 000000000..e6afaa59d --- /dev/null +++ b/pyextra/jwt/contrib/algorithms/pycrypto.py @@ -0,0 +1,47 @@ +import Crypto.Hash.SHA256 +import Crypto.Hash.SHA384 +import Crypto.Hash.SHA512 + +from Crypto.PublicKey import RSA +from Crypto.Signature import PKCS1_v1_5 + +from jwt.algorithms import Algorithm +from jwt.compat import string_types, text_type + + +class RSAAlgorithm(Algorithm): + """ + Performs signing and verification operations using + RSASSA-PKCS-v1_5 and the specified hash function. + + This class requires PyCrypto package to be installed. + + This is based off of the implementation in PyJWT 0.3.2 + """ + SHA256 = Crypto.Hash.SHA256 + SHA384 = Crypto.Hash.SHA384 + SHA512 = Crypto.Hash.SHA512 + + def __init__(self, hash_alg): + self.hash_alg = hash_alg + + def prepare_key(self, key): + + if isinstance(key, RSA._RSAobj): + return key + + if isinstance(key, string_types): + if isinstance(key, text_type): + key = key.encode('utf-8') + + key = RSA.importKey(key) + else: + raise TypeError('Expecting a PEM- or RSA-formatted key.') + + return key + + def sign(self, msg, key): + return PKCS1_v1_5.new(key).sign(self.hash_alg.new(msg)) + + def verify(self, msg, key, sig): + return PKCS1_v1_5.new(key).verify(self.hash_alg.new(msg), sig) diff --git a/pyextra/jwt/exceptions.py b/pyextra/jwt/exceptions.py new file mode 100644 index 000000000..31177a0a2 --- /dev/null +++ b/pyextra/jwt/exceptions.py @@ -0,0 +1,48 @@ +class InvalidTokenError(Exception): + pass + + +class DecodeError(InvalidTokenError): + pass + + +class ExpiredSignatureError(InvalidTokenError): + pass + + +class InvalidAudienceError(InvalidTokenError): + pass + + +class InvalidIssuerError(InvalidTokenError): + pass + + +class InvalidIssuedAtError(InvalidTokenError): + pass + + +class ImmatureSignatureError(InvalidTokenError): + pass + + +class InvalidKeyError(Exception): + pass + + +class InvalidAlgorithmError(InvalidTokenError): + pass + + +class MissingRequiredClaimError(InvalidTokenError): + def __init__(self, claim): + self.claim = claim + + def __str__(self): + return 'Token is missing the "%s" claim' % self.claim + + +# Compatibility aliases (deprecated) +ExpiredSignature = ExpiredSignatureError +InvalidAudience = InvalidAudienceError +InvalidIssuer = InvalidIssuerError diff --git a/pyextra/jwt/utils.py b/pyextra/jwt/utils.py new file mode 100644 index 000000000..637b89299 --- /dev/null +++ b/pyextra/jwt/utils.py @@ -0,0 +1,67 @@ +import base64 +import binascii + +try: + from cryptography.hazmat.primitives.asymmetric.utils import ( + decode_rfc6979_signature, encode_rfc6979_signature + ) +except ImportError: + pass + + +def base64url_decode(input): + rem = len(input) % 4 + + if rem > 0: + input += b'=' * (4 - rem) + + return base64.urlsafe_b64decode(input) + + +def base64url_encode(input): + return base64.urlsafe_b64encode(input).replace(b'=', b'') + + +def merge_dict(original, updates): + if not updates: + return original + + try: + merged_options = original.copy() + merged_options.update(updates) + except (AttributeError, ValueError) as e: + raise TypeError('original and updates must be a dictionary: %s' % e) + + return merged_options + + +def number_to_bytes(num, num_bytes): + padded_hex = '%0*x' % (2 * num_bytes, num) + big_endian = binascii.a2b_hex(padded_hex.encode('ascii')) + return big_endian + + +def bytes_to_number(string): + return int(binascii.b2a_hex(string), 16) + + +def der_to_raw_signature(der_sig, curve): + num_bits = curve.key_size + num_bytes = (num_bits + 7) // 8 + + r, s = decode_rfc6979_signature(der_sig) + + return number_to_bytes(r, num_bytes) + number_to_bytes(s, num_bytes) + + +def raw_to_der_signature(raw_sig, curve): + num_bits = curve.key_size + num_bytes = (num_bits + 7) // 8 + + if len(raw_sig) != 2 * num_bytes: + raise ValueError('Invalid signature') + + r = bytes_to_number(raw_sig[:num_bytes]) + s = bytes_to_number(raw_sig[num_bytes:]) + + return encode_rfc6979_signature(r, s) diff --git a/requirements_openpilot.txt b/requirements_openpilot.txt index 880073ee7..a36aa048e 100644 --- a/requirements_openpilot.txt +++ b/requirements_openpilot.txt @@ -4,6 +4,7 @@ Cython==0.27.3 Flask==1.0.2 #PyGObject==3.28.2 This is installed on the EON, but requires a ton of dependencies to install +PyJWT==1.4.1 PyYAML==3.12 appdirs==1.4.0 atomicwrites==1.1.5 diff --git a/selfdrive/boardd/Makefile b/selfdrive/boardd/Makefile index 7dfbb225c..7bd22add3 100644 --- a/selfdrive/boardd/Makefile +++ b/selfdrive/boardd/Makefile @@ -64,7 +64,7 @@ boardd: $(OBJS) boardd.o: boardd.cc @echo "[ CXX ] $@" - $(CXX) $(CXXFLAGS) \ + $(CXX) $(CXXFLAGS) -MMD \ -I$(PHONELIBS)/android_system_core/include \ $(CEREAL_CFLAGS) \ $(CEREAL_CXXFLAGS) \ diff --git a/selfdrive/boardd/boardd.cc b/selfdrive/boardd/boardd.cc index 3b293307a..3ee867083 100644 --- a/selfdrive/boardd/boardd.cc +++ b/selfdrive/boardd/boardd.cc @@ -21,6 +21,7 @@ #include "cereal/gen/cpp/log.capnp.h" #include "cereal/gen/cpp/car.capnp.h" +#include "common/messaging.h" #include "common/params.h" #include "common/swaglog.h" #include "common/timing.h" @@ -34,7 +35,6 @@ #define SAFETY_NOOUTPUT 0 #define SAFETY_HONDA 1 #define SAFETY_TOYOTA 2 -#define SAFETY_ELM327 0xE327 #define SAFETY_GM 3 #define SAFETY_HONDA_BOSCH 4 #define SAFETY_FORD 5 @@ -46,7 +46,7 @@ #define SAFETY_TOYOTA_IPAS 0x1335 #define SAFETY_TOYOTA_NOLIMITS 0x1336 #define SAFETY_ALLOUTPUT 0x1337 -#define SAFETY_ELM327 0xE327 +#define SAFETY_ELM327 0xE327 // diagnostic only namespace { @@ -138,6 +138,9 @@ void *safety_setter_thread(void *s) { // set in the mutex to avoid race safety_setter_thread_handle = -1; + // set if long_control is allowed by openpilot. Hardcoded to True for now + libusb_control_transfer(dev_handle, 0x40, 0xdf, 1, 0, NULL, 0, TIMEOUT); + libusb_control_transfer(dev_handle, 0x40, 0xdc, safety_setting, safety_param, NULL, 0, TIMEOUT); pthread_mutex_unlock(&usb_lock); @@ -173,12 +176,8 @@ bool usb_connect() { LOGW("not enabling charging on x86_64"); #endif - // no output is the default - if (getenv("RECVMOCK")) { - libusb_control_transfer(dev_handle, 0x40, 0xdc, SAFETY_ELM327, 0, NULL, 0, TIMEOUT); - } else { - libusb_control_transfer(dev_handle, 0x40, 0xdc, SAFETY_NOOUTPUT, 0, NULL, 0, TIMEOUT); - } + // diagnostic only is the default, needed for VIN query + libusb_control_transfer(dev_handle, 0x40, 0xdc, SAFETY_ELM327, 0, NULL, 0, TIMEOUT); if (safety_setter_thread_handle == -1) { err = pthread_create(&safety_setter_thread_handle, NULL, safety_setter_thread, NULL); @@ -223,6 +222,8 @@ void can_recv(void *s) { int recv; uint32_t f1, f2; + uint64_t start_time = nanos_since_boot(); + // do recv pthread_mutex_lock(&usb_lock); @@ -245,12 +246,13 @@ void can_recv(void *s) { // create message capnp::MallocMessageBuilder msg; cereal::Event::Builder event = msg.initRoot(); - event.setLogMonoTime(nanos_since_boot()); + event.setLogMonoTime(start_time); + size_t num_msg = recv / 0x10; - auto canData = event.initCan(recv/0x10); + auto canData = event.initCan(num_msg); // populate message - for (int i = 0; i<(recv/0x10); i++) { + for (int i = 0; i < num_msg; i++) { if (data[i*4] & 4) { // extended canData[i].setAddress(data[i*4] >> 3); @@ -380,59 +382,14 @@ void can_send(void *s) { free(send); } - // **** threads **** -void *thermal_thread(void *crap) { - int err; - LOGD("start thermal thread"); - - // thermal = 8005 - void *context = zmq_ctx_new(); - void *subscriber = zmq_socket(context, ZMQ_SUB); - zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, "", 0); - zmq_connect(subscriber, "tcp://127.0.0.1:8005"); - - // run as fast as messages come in - while (!do_exit) { - // recv from thermal - zmq_msg_t msg; - zmq_msg_init(&msg); - err = zmq_msg_recv(&msg, subscriber, 0); - assert(err >= 0); - - // format for board, make copy due to alignment issues, will be freed on out of scope - // copied from send thread... - auto amsg = kj::heapArray((zmq_msg_size(&msg) / sizeof(capnp::word)) + 1); - memcpy(amsg.begin(), zmq_msg_data(&msg), zmq_msg_size(&msg)); - - capnp::FlatArrayMessageReader cmsg(amsg); - cereal::Event::Reader event = cmsg.getRoot(); - - uint16_t target_fan_speed = event.getThermal().getFanSpeed(); - //LOGW("setting fan speed %d", target_fan_speed); - - pthread_mutex_lock(&usb_lock); - libusb_control_transfer(dev_handle, 0xc0, 0xd3, target_fan_speed, 0, NULL, 0, TIMEOUT); - pthread_mutex_unlock(&usb_lock); - - zmq_msg_close(&msg); - } - - // turn the fan off when we exit - libusb_control_transfer(dev_handle, 0xc0, 0xd3, 0, 0, NULL, 0, TIMEOUT); - - return NULL; -} - void *can_send_thread(void *crap) { LOGD("start send thread"); // sendcan = 8017 void *context = zmq_ctx_new(); - void *subscriber = zmq_socket(context, ZMQ_SUB); - zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, "", 0); - zmq_connect(subscriber, "tcp://127.0.0.1:8017"); + void *subscriber = sub_sock(context, "tcp://127.0.0.1:8017"); // drain sendcan to delete any stale messages from previous runs zmq_msg_t msg; @@ -457,11 +414,24 @@ void *can_recv_thread(void *crap) { void *publisher = zmq_socket(context, ZMQ_PUB); zmq_bind(publisher, "tcp://*:8006"); - // run at ~200hz + // run at 100hz + const uint64_t dt = 10000000ULL; + uint64_t next_frame_time = nanos_since_boot() + dt; + while (!do_exit) { can_recv(publisher); - // 5ms - usleep(5*1000); + + uint64_t cur_time = nanos_since_boot(); + int64_t remaining = next_frame_time - cur_time; + if (remaining > 0){ + useconds_t sleep = remaining / 1000; + usleep(sleep); + } else { + LOGW("missed cycle"); + next_frame_time = cur_time; + } + + next_frame_time += dt; } return NULL; } @@ -686,16 +656,8 @@ int main() { can_recv_thread, NULL); assert(err == 0); - pthread_t thermal_thread_handle; - err = pthread_create(&thermal_thread_handle, NULL, - thermal_thread, NULL); - assert(err == 0); - // join threads - err = pthread_join(thermal_thread_handle, NULL); - assert(err == 0); - err = pthread_join(can_recv_thread_handle, NULL); assert(err == 0); diff --git a/selfdrive/can/libdbc_py.py b/selfdrive/can/libdbc_py.py index cf712cf63..61cf8cd05 100644 --- a/selfdrive/can/libdbc_py.py +++ b/selfdrive/can/libdbc_py.py @@ -78,9 +78,9 @@ typedef struct { void* can_init(int bus, const char* dbc_name, size_t num_message_options, const MessageParseOptions* message_options, size_t num_signal_options, const SignalParseOptions* signal_options, bool sendcan, - const char* tcp_addr); + const char* tcp_addr, int timeout); -void can_update(void* can, uint64_t sec, bool wait); +int can_update(void* can, uint64_t sec, bool wait); size_t can_query(void* can, uint64_t sec, bool *out_can_valid, size_t out_values_size, SignalValue* out_values); diff --git a/selfdrive/can/parser.cc b/selfdrive/can/parser.cc index b6845b47d..eb828cd8e 100644 --- a/selfdrive/can/parser.cc +++ b/selfdrive/can/parser.cc @@ -190,12 +190,13 @@ class CANParser { CANParser(int abus, const std::string& dbc_name, const std::vector &options, const std::vector &sigoptions, - bool sendcan, const std::string& tcp_addr) + bool sendcan, const std::string& tcp_addr, int timeout=-1) : bus(abus) { // connect to can on 8006 context = zmq_ctx_new(); subscriber = zmq_socket(context, ZMQ_SUB); zmq_setsockopt(subscriber, ZMQ_SUBSCRIBE, "", 0); + zmq_setsockopt(subscriber, ZMQ_RCVTIMEO, &timeout, sizeof(int)); std::string tcp_addr_str; @@ -325,8 +326,9 @@ class CANParser { } } - void update(uint64_t sec, bool wait) { + int update(uint64_t sec, bool wait) { int err; + int result = 0; // recv from can zmq_msg_t msg; @@ -338,6 +340,11 @@ class CANParser { if (first) { err = zmq_msg_recv(&msg, subscriber, 0); first = false; + + // When we timeout on the first message, return error + if (err < 0){ + result = -1; + } } else { err = zmq_msg_recv(&msg, subscriber, ZMQ_DONTWAIT); } @@ -352,13 +359,12 @@ class CANParser { cereal::Event::Reader event = cmsg.getRoot(); auto cans = event.getCan(); - UpdateCans(sec, cans); } UpdateValid(sec); - zmq_msg_close(&msg); + return result; } std::vector query(uint64_t sec) { @@ -401,18 +407,18 @@ extern "C" { void* can_init(int bus, const char* dbc_name, size_t num_message_options, const MessageParseOptions* message_options, size_t num_signal_options, const SignalParseOptions* signal_options, - bool sendcan, const char* tcp_addr) { + bool sendcan, const char* tcp_addr, int timeout) { CANParser* ret = new CANParser(bus, std::string(dbc_name), (message_options ? std::vector(message_options, message_options+num_message_options) : std::vector{}), (signal_options ? std::vector(signal_options, signal_options+num_signal_options) - : std::vector{}), sendcan, std::string(tcp_addr)); + : std::vector{}), sendcan, std::string(tcp_addr), timeout); return (void*)ret; } -void can_update(void* can, uint64_t sec, bool wait) { +int can_update(void* can, uint64_t sec, bool wait) { CANParser* cp = (CANParser*)can; - cp->update(sec, wait); + return cp->update(sec, wait); } size_t can_query(void* can, uint64_t sec, bool *out_can_valid, size_t out_values_size, SignalValue* out_values) { diff --git a/selfdrive/can/parser.py b/selfdrive/can/parser.py index 2e8384f63..31af2df04 100644 --- a/selfdrive/can/parser.py +++ b/selfdrive/can/parser.py @@ -6,7 +6,7 @@ from selfdrive.can.libdbc_py import libdbc, ffi class CANParser(object): - def __init__(self, dbc_name, signals, checks=None, bus=0, sendcan=False, tcp_addr="127.0.0.1"): + def __init__(self, dbc_name, signals, checks=None, bus=0, sendcan=False, tcp_addr="127.0.0.1", timeout=-1): if checks is None: checks = [] @@ -61,7 +61,7 @@ class CANParser(object): } for msg_address, freq in message_options.items()]) self.can = libdbc.can_init(bus, dbc_name, len(message_options_c), message_options_c, - len(signal_options_c), signal_options_c, sendcan, tcp_addr) + len(signal_options_c), signal_options_c, sendcan, tcp_addr, timeout) self.p_can_valid = ffi.new("bool*") @@ -94,8 +94,10 @@ class CANParser(object): return ret def update(self, sec, wait): - libdbc.can_update(self.can, sec, wait) - return self.update_vl(sec) + """Returns if the update was successfull (e.g. no rcv timeout happened)""" + r = libdbc.can_update(self.can, sec, wait) + return bool(r >= 0), self.update_vl(sec) + class CANDefine(object): def __init__(self, dbc_name): diff --git a/selfdrive/can/tests/test_packer_honda.py b/selfdrive/can/tests/test_packer_honda.py index 58b841f5a..87d62244e 100644 --- a/selfdrive/can/tests/test_packer_honda.py +++ b/selfdrive/can/tests/test_packer_honda.py @@ -41,8 +41,9 @@ class TestPackerMethods(unittest.TestCase): random.randint(0, 65536), random.randint(0, 65536), random.randint(0, 65536)) car_fingerprint = HONDA_BOSCH[0] idx = random.randint(0, 65536) - m_old = hondacan.create_ui_commands(self.honda_cp_old, pcm_speed, hud, car_fingerprint, idx) - m = hondacan.create_ui_commands(self.honda_cp, pcm_speed, hud, car_fingerprint, idx) + is_metric = (random.randint(0, 2) % 2 == 0) + m_old = hondacan.create_ui_commands(self.honda_cp_old, pcm_speed, hud, car_fingerprint, is_metric, idx) + m = hondacan.create_ui_commands(self.honda_cp, pcm_speed, hud, car_fingerprint, is_metric, idx) self.assertEqual(m_old, m) button_val = random.randint(0, 65536) diff --git a/selfdrive/car/car_helpers.py b/selfdrive/car/car_helpers.py index 58cde11bd..ef807abb6 100644 --- a/selfdrive/car/car_helpers.py +++ b/selfdrive/car/car_helpers.py @@ -1,20 +1,34 @@ import os import time +from common.vin import is_vin_response_valid from common.basedir import BASEDIR from common.realtime import sec_since_boot from common.fingerprints import eliminate_incompatible_cars, all_known_cars +from selfdrive.boardd.boardd import can_list_to_can_capnp from selfdrive.swaglog import cloudlog import selfdrive.messaging as messaging -def load_interfaces(x): + +def get_startup_alert(car_recognized, controller_available): + alert = 'startup' + if not car_recognized: + alert = 'startupNoCar' + elif car_recognized and not controller_available: + alert = 'startupNoControl' + return alert + + +def load_interfaces(brand_names): ret = {} - for interface in x: - try: - imp = __import__('selfdrive.car.%s.interface' % interface, fromlist=['CarInterface']).CarInterface - except ImportError: - imp = None - for car in x[interface]: - ret[car] = imp + for brand_name in brand_names: + path = ('selfdrive.car.%s' % brand_name) + CarInterface = __import__(path + '.interface', fromlist=['CarInterface']).CarInterface + if os.path.exists(BASEDIR + '/' + path.replace('.', '/') + '/carcontroller.py'): + CarController = __import__(path + '.carcontroller', fromlist=['CarController']).CarController + else: + CarController = None + for model_name in brand_names[brand_name]: + ret[model_name] = (CarInterface, CarController) return ret @@ -22,17 +36,17 @@ def _get_interface_names(): # read all the folders in selfdrive/car and return a dict where: # - keys are all the car names that which we have an interface for # - values are lists of spefic car models for a given car - interface_names = {} + brand_names = {} for car_folder in [x[0] for x in os.walk(BASEDIR + '/selfdrive/car')]: try: - car_name = car_folder.split('/')[-1] - model_names = __import__('selfdrive.car.%s.values' % car_name, fromlist=['CAR']).CAR + brand_name = car_folder.split('/')[-1] + model_names = __import__('selfdrive.car.%s.values' % brand_name, fromlist=['CAR']).CAR model_names = [getattr(model_names, c) for c in model_names.__dict__.keys() if not c.startswith("__")] - interface_names[car_name] = model_names + brand_names[brand_name] = model_names except (ImportError, IOError): pass - return interface_names + return brand_names # imports from directory selfdrive/car// @@ -41,68 +55,96 @@ interfaces = load_interfaces(_get_interface_names()) # BOUNTY: every added fingerprint in selfdrive/car/*/values.py is a $100 coupon code on shop.comma.ai # **** for use live only **** -def fingerprint(logcan, timeout): +def fingerprint(logcan, sendcan): if os.getenv("SIMULATOR2") is not None: - return ("simulator2", None) + return ("simulator2", None, "") elif os.getenv("SIMULATOR") is not None: - return ("simulator", None) + return ("simulator", None, "") + finger = {} cloudlog.warning("waiting for fingerprint...") candidate_cars = all_known_cars() - finger = {} - st = None - st_passive = sec_since_boot() # only relevant when passive + can_seen_ts = None can_seen = False + + # works on standard 11-bit addresses for diagnostic. Tested on Toyota and Subaru; + # Honda uses the extended 29-bit addresses, and unfortunately only works from OBDII + vin_query_msg = [[0x7df, 0, '\x02\x09\x02'.ljust(8, "\x00"), 0], + [0x7e0, 0, '\x30'.ljust(8, "\x00"), 0]] + + vin_cnts = [1, 2] # number of messages to wait for at each iteration + vin_step = 0 + vin_cnt = 0 + vin_responded = False + vin_never_responded = True + vin_dat = [] + vin = "" + while 1: for a in messaging.drain_sock(logcan): for can in a.can: can_seen = True + + # have we got a VIN query response? + if can.src == 0 and can.address == 0x7e8: + vin_never_responded = False + # basic sanity checks on ISO-TP response + if is_vin_response_valid(can.dat, vin_step, vin_cnt): + vin_dat += can.dat[2:] if vin_step == 0 else can.dat[1:] + vin_cnt += 1 + if vin_cnt == vin_cnts[vin_step]: + vin_responded = True + vin_step += 1 + # ignore everything not on bus 0 and with more than 11 bits, - # which are ussually sporadic and hard to include in fingerprints - if can.src == 0 and can.address < 0x800: + # which are ussually sporadic and hard to include in fingerprints. + # also exclude VIN query response on 0x7e8 + if can.src == 0 and can.address < 0x800 and can.address != 0x7e8: finger[can.address] = len(can.dat) candidate_cars = eliminate_incompatible_cars(can, candidate_cars) - if st is None and can_seen: - st = sec_since_boot() # start time + if can_seen_ts is None and can_seen: + can_seen_ts = sec_since_boot() # start time ts = sec_since_boot() # if we only have one car choice and the time_fingerprint since we got our first # message has elapsed, exit. Toyota needs higher time_fingerprint, since DSU does not # broadcast immediately - if len(candidate_cars) == 1 and st is not None: - # TODO: better way to decide to wait more if Toyota + if len(candidate_cars) == 1 and can_seen_ts is not None: time_fingerprint = 1.0 if ("TOYOTA" in candidate_cars[0] or "LEXUS" in candidate_cars[0]) else 0.1 - if (ts-st) > time_fingerprint: + if (ts - can_seen_ts) > time_fingerprint: break - # bail if no cars left or we've been waiting too long - elif len(candidate_cars) == 0 or (timeout and (ts - st_passive) > timeout): - return None, finger + # bail if no cars left or we've been waiting for more than 2s since can_seen + elif len(candidate_cars) == 0 or (can_seen_ts is not None and (ts - can_seen_ts) > 2.): + return None, finger, "" + + # keep sending VIN qury if ECU isn't responsing. + # sendcan is probably not ready due to the zmq slow joiner syndrome + if can_seen and (vin_never_responded or (vin_responded and vin_step < len(vin_cnts))): + sendcan.send(can_list_to_can_capnp([vin_query_msg[vin_step]], msgtype='sendcan')) + vin_responded = False + vin_cnt = 0 time.sleep(0.01) + # only report vin if procedure is finished + if vin_step == len(vin_cnts) and vin_cnt == vin_cnts[-1]: + vin = "".join(vin_dat[3:]) + cloudlog.warning("fingerprinted %s", candidate_cars[0]) - return (candidate_cars[0], finger) + cloudlog.warning("VIN %s", vin) + return candidate_cars[0], finger, vin -def get_car(logcan, sendcan=None, passive=True): - # TODO: timeout only useful for replays so controlsd can start before unlogger - timeout = 2. if passive else None - candidate, fingerprints = fingerprint(logcan, timeout) +def get_car(logcan, sendcan): + + candidate, fingerprints, vin = fingerprint(logcan, sendcan) if candidate is None: cloudlog.warning("car doesn't match any fingerprints: %r", fingerprints) - if passive: - candidate = "mock" - else: - return None, None + candidate = "mock" - interface_cls = interfaces[candidate] + CarInterface, CarController = interfaces[candidate] + params = CarInterface.get_params(candidate, fingerprints, vin) - if interface_cls is None: - cloudlog.warning("car matched %s, but interface wasn't available or failed to import" % candidate) - return None, None - - params = interface_cls.get_params(candidate, fingerprints) - - return interface_cls(params, sendcan), params + return CarInterface(params, CarController), params diff --git a/selfdrive/car/chrysler/carcontroller.py b/selfdrive/car/chrysler/carcontroller.py index c6a1f9d29..eea51f8f6 100644 --- a/selfdrive/car/chrysler/carcontroller.py +++ b/selfdrive/car/chrysler/carcontroller.py @@ -1,5 +1,4 @@ from cereal import car -from selfdrive.boardd.boardd import can_list_to_can_capnp from selfdrive.car import apply_toyota_steer_torque_limits from selfdrive.car.chrysler.chryslercan import create_lkas_hud, create_lkas_command, \ create_wheel_buttons, \ @@ -38,12 +37,11 @@ class CarController(object): self.packer = CANPacker(dbc_name) - def update(self, sendcan, enabled, CS, frame, actuators, - pcm_cancel_cmd, hud_alert, audible_alert): + def update(self, enabled, CS, frame, actuators, pcm_cancel_cmd, hud_alert, audible_alert): # this seems needed to avoid steering faults and to force the sync with the EPS counter frame = CS.lkas_counter if self.prev_frame == frame: - return + return [] # *** compute control surfaces *** # steer torque @@ -97,4 +95,5 @@ class CarController(object): self.ccframe += 1 self.prev_frame = frame - sendcan.send(can_list_to_can_capnp(can_sends, msgtype='sendcan')) + + return can_sends diff --git a/selfdrive/car/chrysler/carstate.py b/selfdrive/car/chrysler/carstate.py index 94effcf93..7f4ad675d 100644 --- a/selfdrive/car/chrysler/carstate.py +++ b/selfdrive/car/chrysler/carstate.py @@ -60,7 +60,7 @@ def get_can_parser(CP): ("ACC_2", 50), ] - return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 0) + return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 0, timeout=100) def get_camera_parser(CP): signals = [ @@ -72,7 +72,7 @@ def get_camera_parser(CP): ] checks = [] - return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 2) + return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 2, timeout=100) class CarState(object): diff --git a/selfdrive/car/chrysler/interface.py b/selfdrive/car/chrysler/interface.py index 2c3d7455a..cef9698fd 100755 --- a/selfdrive/car/chrysler/interface.py +++ b/selfdrive/car/chrysler/interface.py @@ -7,14 +7,9 @@ from selfdrive.controls.lib.vehicle_model import VehicleModel from selfdrive.car.chrysler.carstate import CarState, get_can_parser, get_camera_parser from selfdrive.car.chrysler.values import ECU, check_ecu_msgs, CAR -try: - from selfdrive.car.chrysler.carcontroller import CarController -except ImportError: - CarController = None - class CarInterface(object): - def __init__(self, CP, sendcan=None): + def __init__(self, CP, CarController): self.CP = CP self.VM = VehicleModel(CP) @@ -30,9 +25,8 @@ class CarInterface(object): self.cp = get_can_parser(CP) self.cp_cam = get_camera_parser(CP) - # sending if read only is False - if sendcan is not None: - self.sendcan = sendcan + self.CC = None + if CarController is not None: self.CC = CarController(self.cp.dbc_name, CP.carFingerprint, CP.enableCamera) @staticmethod @@ -44,7 +38,7 @@ class CarInterface(object): return 1.0 @staticmethod - def get_params(candidate, fingerprint): + def get_params(candidate, fingerprint, vin=""): # kg of standard extra cargo to count for drive, gas, etc... std_cargo = 136 @@ -53,6 +47,7 @@ class CarInterface(object): ret.carName = "chrysler" ret.carFingerprint = candidate + ret.carVin = vin ret.safetyModel = car.CarParams.SafetyModels.chrysler @@ -140,8 +135,10 @@ class CarInterface(object): def update(self, c): # ******************* do can recv ******************* canMonoTimes = [] - self.cp.update(int(sec_since_boot() * 1e9), False) - self.cp_cam.update(int(sec_since_boot() * 1e9), False) + can_valid, _ = self.cp.update(int(sec_since_boot() * 1e9), True) + cam_valid, _ = self.cp_cam.update(int(sec_since_boot() * 1e9), False) + can_rcv_error = not can_valid or not cam_valid + self.CS.update(self.cp, self.cp_cam) # create message @@ -217,10 +214,12 @@ class CarInterface(object): events = [] if not self.CS.can_valid: self.can_invalid_count += 1 - if self.can_invalid_count >= 5: - events.append(create_event('commIssue', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) else: self.can_invalid_count = 0 + + if can_rcv_error or self.can_invalid_count >= 5: + events.append(create_event('commIssue', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) + if not (ret.gearShifter in ('drive', 'low')): events.append(create_event('wrongGear', [ET.NO_ENTRY, ET.SOFT_DISABLE])) if ret.doorOpen: @@ -263,11 +262,11 @@ class CarInterface(object): def apply(self, c): if (self.CS.frame == -1): - return False # if we haven't seen a frame 220, then do not update. + return [] # if we haven't seen a frame 220, then do not update. self.frame = self.CS.frame - self.CC.update(self.sendcan, c.enabled, self.CS, self.frame, - c.actuators, c.cruiseControl.cancel, c.hudControl.visualAlert, - c.hudControl.audibleAlert) + can_sends = self.CC.update(c.enabled, self.CS, self.frame, + c.actuators, c.cruiseControl.cancel, c.hudControl.visualAlert, + c.hudControl.audibleAlert) - return False + return can_sends diff --git a/selfdrive/car/chrysler/radar_interface.py b/selfdrive/car/chrysler/radar_interface.py index 54bd1b314..e5359fad8 100755 --- a/selfdrive/car/chrysler/radar_interface.py +++ b/selfdrive/car/chrysler/radar_interface.py @@ -13,7 +13,7 @@ RADAR_MSGS_D = range(0x2a2, 0x2b4+2, 2) # d_ messages LAST_MSG = max(RADAR_MSGS_C + RADAR_MSGS_D) NUMBER_MSGS = len(RADAR_MSGS_C) + len(RADAR_MSGS_D) -def _create_radard_can_parser(): +def _create_radar_can_parser(): dbc_f = 'chrysler_pacifica_2017_hybrid_private_fusion.dbc' msg_n = len(RADAR_MSGS_C) # list of [(signal name, message name or number, initial values), (...)] @@ -54,7 +54,7 @@ class RadarInterface(object): def __init__(self, CP): self.pts = {} self.delay = 0.0 # Delay of radar #TUNE - self.rcp = _create_radard_can_parser() + self.rcp = _create_radar_can_parser() context = zmq.Context() self.logcan = messaging.sub_sock(context, service_list['can'].port) @@ -65,11 +65,12 @@ class RadarInterface(object): while 1: tm = int(sec_since_boot() * 1e9) - updated_messages.update(self.rcp.update(tm, True)) + _, vls = self.rcp.update(tm, True) + updated_messages.update(vls) if LAST_MSG in updated_messages: break - ret = car.RadarState.new_message() + ret = car.RadarData.new_message() errors = [] if not self.rcp.can_valid: errors.append("commIssue") @@ -81,7 +82,7 @@ class RadarInterface(object): trackId = _address_to_track(ii) if trackId not in self.pts: - self.pts[trackId] = car.RadarState.RadarPoint.new_message() + self.pts[trackId] = car.RadarData.RadarPoint.new_message() self.pts[trackId].trackId = trackId self.pts[trackId].aRel = float('nan') self.pts[trackId].yvRel = float('nan') diff --git a/selfdrive/car/ford/carstate.py b/selfdrive/car/ford/carstate.py index 2c7a27eb3..2e26eb7c6 100644 --- a/selfdrive/car/ford/carstate.py +++ b/selfdrive/car/ford/carstate.py @@ -29,7 +29,7 @@ def get_can_parser(CP): checks = [ ] - return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 0) + return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 0, timeout=100) class CarState(object): diff --git a/selfdrive/car/ford/interface.py b/selfdrive/car/ford/interface.py index a46681eb4..439e561a4 100755 --- a/selfdrive/car/ford/interface.py +++ b/selfdrive/car/ford/interface.py @@ -8,14 +8,9 @@ from selfdrive.controls.lib.vehicle_model import VehicleModel from selfdrive.car.ford.carstate import CarState, get_can_parser from selfdrive.car.ford.values import MAX_ANGLE -try: - from selfdrive.car.ford.carcontroller import CarController -except ImportError: - CarController = None - class CarInterface(object): - def __init__(self, CP, sendcan=None): + def __init__(self, CP, CarController): self.CP = CP self.VM = VehicleModel(CP) @@ -30,9 +25,8 @@ class CarInterface(object): self.cp = get_can_parser(CP) - # sending if read only is False - if sendcan is not None: - self.sendcan = sendcan + self.CC = None + if CarController is not None: self.CC = CarController(self.cp.dbc_name, CP.enableCamera, self.VM) @staticmethod @@ -44,7 +38,7 @@ class CarInterface(object): return 1.0 @staticmethod - def get_params(candidate, fingerprint): + def get_params(candidate, fingerprint, vin=""): # kg of standard extra cargo to count for drive, gas, etc... std_cargo = 136 @@ -53,6 +47,7 @@ class CarInterface(object): ret.carName = "ford" ret.carFingerprint = candidate + ret.carVin = vin ret.safetyModel = car.CarParams.SafetyModels.ford @@ -138,7 +133,8 @@ class CarInterface(object): # ******************* do can recv ******************* canMonoTimes = [] - self.cp.update(int(sec_since_boot() * 1e9), False) + can_valid, _ = self.cp.update(int(sec_since_boot() * 1e9), True) + can_rcv_error = not can_valid self.CS.update(self.cp) @@ -174,11 +170,12 @@ class CarInterface(object): events = [] if not self.CS.can_valid: self.can_invalid_count += 1 - if self.can_invalid_count >= 5: - events.append(create_event('commIssue', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) else: self.can_invalid_count = 0 + if can_rcv_error or self.can_invalid_count >= 5: + events.append(create_event('commIssue', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) + if self.CS.steer_error: events.append(create_event('steerUnavailable', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE, ET.PERMANENT])) @@ -212,8 +209,8 @@ class CarInterface(object): # to be called @ 100hz def apply(self, c): - self.CC.update(self.sendcan, c.enabled, self.CS, self.frame, c.actuators, - c.hudControl.visualAlert, c.cruiseControl.cancel) + can_sends = self.CC.update(c.enabled, self.CS, self.frame, c.actuators, + c.hudControl.visualAlert, c.cruiseControl.cancel) self.frame += 1 - return False + return can_sends diff --git a/selfdrive/car/ford/radar_interface.py b/selfdrive/car/ford/radar_interface.py index c42bc3e8f..a49ad413c 100755 --- a/selfdrive/car/ford/radar_interface.py +++ b/selfdrive/car/ford/radar_interface.py @@ -11,7 +11,7 @@ import selfdrive.messaging as messaging RADAR_MSGS = range(0x500, 0x540) -def _create_radard_can_parser(): +def _create_radar_can_parser(): dbc_f = 'ford_fusion_2018_adas.dbc' msg_n = len(RADAR_MSGS) signals = list(zip(['X_Rel'] * msg_n + ['Angle'] * msg_n + ['V_Rel'] * msg_n, @@ -31,7 +31,7 @@ class RadarInterface(object): self.delay = 0.0 # Delay of radar # Nidec - self.rcp = _create_radard_can_parser() + self.rcp = _create_radar_can_parser() context = zmq.Context() self.logcan = messaging.sub_sock(context, service_list['can'].port) @@ -42,12 +42,14 @@ class RadarInterface(object): updated_messages = set() while 1: tm = int(sec_since_boot() * 1e9) - updated_messages.update(self.rcp.update(tm, True)) + _, vls = self.rcp.update(tm, True) + updated_messages.update(vls) + # TODO: do not hardcode last msg if 0x53f in updated_messages: break - ret = car.RadarState.new_message() + ret = car.RadarData.new_message() errors = [] if not self.rcp.can_valid: errors.append("commIssue") @@ -69,7 +71,7 @@ class RadarInterface(object): # radar point only valid if there have been enough valid measurements if self.validCnt[ii] > 0: if ii not in self.pts: - self.pts[ii] = car.RadarState.RadarPoint.new_message() + self.pts[ii] = car.RadarData.RadarPoint.new_message() self.pts[ii].trackId = self.track_id self.track_id += 1 self.pts[ii].dRel = cpt['X_Rel'] # from front of car diff --git a/selfdrive/car/gm/carcontroller.py b/selfdrive/car/gm/carcontroller.py index 26cfd84d3..000f7dde6 100644 --- a/selfdrive/car/gm/carcontroller.py +++ b/selfdrive/car/gm/carcontroller.py @@ -1,12 +1,13 @@ +from cereal import car from common.numpy_fast import interp from common.realtime import sec_since_boot from selfdrive.config import Conversions as CV -from selfdrive.boardd.boardd import can_list_to_can_capnp from selfdrive.car import apply_std_steer_torque_limits from selfdrive.car.gm import gmcan from selfdrive.car.gm.values import DBC, SUPERCRUISE_CARS from selfdrive.can.packer import CANPacker +VisualAlert = car.CarControl.HUDControl.VisualAlert class CarControllerParams(): def __init__(self, car_fingerprint): @@ -59,16 +60,21 @@ def actuator_hystereses(final_pedal, pedal_steady): return final_pedal, pedal_steady +def process_hud_alert(hud_alert): + # initialize to no alert + steer = 0 + if hud_alert == VisualAlert.steerRequired: + steer = 1 + return steer class CarController(object): - def __init__(self, canbus, car_fingerprint, allow_controls): + def __init__(self, canbus, car_fingerprint): self.pedal_steady = 0. self.start_time = sec_since_boot() self.chime = 0 self.steer_idx = 0 self.apply_steer_last = 0 self.car_fingerprint = car_fingerprint - self.allow_controls = allow_controls self.lka_icon_status_last = (False, False) # Setup detection helper. Routes commands to @@ -79,13 +85,8 @@ class CarController(object): self.packer_pt = CANPacker(DBC[car_fingerprint]['pt']) self.packer_ch = CANPacker(DBC[car_fingerprint]['chassis']) - def update(self, sendcan, enabled, CS, frame, actuators, \ - hud_v_cruise, hud_show_lanes, hud_show_car, chime, chime_cnt): - """ Controls thread """ - - # Sanity check. - if not self.allow_controls: - return + def update(self, enabled, CS, frame, actuators, \ + hud_v_cruise, hud_show_lanes, hud_show_car, chime, chime_cnt, hud_alert): P = self.params @@ -93,6 +94,9 @@ class CarController(object): can_sends = [] canbus = self.canbus + alert_out = process_hud_alert(hud_alert) + steer = alert_out + ### STEER ### if (frame % P.STEER_STEP) == 0: @@ -175,7 +179,7 @@ class CarController(object): lka_icon_status = (lka_active, lka_critical) if frame % P.CAMERA_KEEPALIVE_STEP == 0 \ or lka_icon_status != self.lka_icon_status_last: - can_sends.append(gmcan.create_lka_icon_command(canbus.sw_gmlan, lka_active, lka_critical)) + can_sends.append(gmcan.create_lka_icon_command(canbus.sw_gmlan, lka_active, lka_critical, steer)) self.lka_icon_status_last = lka_icon_status # Send chimes @@ -195,4 +199,4 @@ class CarController(object): # issued for the same chime type and duration self.chime = chime - sendcan.send(can_list_to_can_capnp(can_sends, msgtype='sendcan')) + return can_sends diff --git a/selfdrive/car/gm/carstate.py b/selfdrive/car/gm/carstate.py index 7a18f320c..350274f2f 100644 --- a/selfdrive/car/gm/carstate.py +++ b/selfdrive/car/gm/carstate.py @@ -47,7 +47,8 @@ def get_powertrain_can_parser(CP, canbus): ("CruiseState", "AcceleratorPedal2", 0), ] - return CANParser(DBC[CP.carFingerprint]['pt'], signals, [], canbus.powertrain) + return CANParser(DBC[CP.carFingerprint]['pt'], signals, [], canbus.powertrain, timeout=100) + class CarState(object): def __init__(self, CP, canbus): diff --git a/selfdrive/car/gm/gmcan.py b/selfdrive/car/gm/gmcan.py index 910cb1d95..64fd84f4a 100644 --- a/selfdrive/car/gm/gmcan.py +++ b/selfdrive/car/gm/gmcan.py @@ -134,8 +134,13 @@ def create_chime_command(bus, chime_type, duration, repeat_cnt): dat = [chime_type, duration, repeat_cnt, 0xff, 0] return [0x10400060, 0, "".join(map(chr, dat)), bus] -def create_lka_icon_command(bus, active, critical): - if active: +def create_lka_icon_command(bus, active, critical, steer): + if active and steer == 1: + if critical: + dat = "\x50\xc0\x14" + else: + dat = "\x50\x40\x18" + elif active: if critical: dat = "\x40\xc0\x14" else: diff --git a/selfdrive/car/gm/interface.py b/selfdrive/car/gm/interface.py index a21b12d31..d8177ccef 100755 --- a/selfdrive/car/gm/interface.py +++ b/selfdrive/car/gm/interface.py @@ -8,10 +8,6 @@ from selfdrive.car.gm.values import DBC, CAR, STOCK_CONTROL_MSGS, AUDIO_HUD, \ SUPERCRUISE_CARS, AccState from selfdrive.car.gm.carstate import CarState, CruiseButtons, get_powertrain_can_parser -try: - from selfdrive.car.gm.carcontroller import CarController -except ImportError: - CarController = None class CanBus(object): def __init__(self): @@ -21,7 +17,7 @@ class CanBus(object): self.sw_gmlan = 3 class CarInterface(object): - def __init__(self, CP, sendcan=None): + def __init__(self, CP, CarController): self.CP = CP self.frame = 0 @@ -37,10 +33,9 @@ class CarInterface(object): self.pt_cp = get_powertrain_can_parser(CP, canbus) self.ch_cp_dbc_name = DBC[CP.carFingerprint]['chassis'] - # sending if read only is False - if sendcan is not None: - self.sendcan = sendcan - self.CC = CarController(canbus, CP.carFingerprint, CP.enableCamera) + self.CC = None + if CarController is not None: + self.CC = CarController(canbus, CP.carFingerprint) @staticmethod def compute_gb(accel, speed): @@ -51,16 +46,17 @@ class CarInterface(object): return 1.0 @staticmethod - def get_params(candidate, fingerprint): + def get_params(candidate, fingerprint, vin=""): ret = car.CarParams.new_message() ret.carName = "gm" ret.carFingerprint = candidate + ret.carVin = vin ret.enableCruise = False # Presence of a camera on the object bus is ok. - # Have to go passive if ASCM is online (ACC-enabled cars), + # Have to go to read_only if ASCM is online (ACC-enabled cars), # or camera is on powertrain bus (LKA cars without ACC). ret.enableCamera = not any(x for x in STOCK_CONTROL_MSGS[candidate] if x in fingerprint) ret.openpilotLongitudinalControl = ret.enableCamera @@ -195,8 +191,8 @@ class CarInterface(object): # returns a car.CarState def update(self, c): - - self.pt_cp.update(int(sec_since_boot() * 1e9), False) + can_valid, _ = self.pt_cp.update(int(sec_since_boot() * 1e9), True) + can_rcv_error = not can_valid self.CS.update(self.pt_cp) # create message @@ -281,10 +277,12 @@ class CarInterface(object): events = [] if not self.CS.can_valid: self.can_invalid_count += 1 - if self.can_invalid_count >= 5: - events.append(create_event('commIssue', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) else: self.can_invalid_count = 0 + + if can_rcv_error or self.can_invalid_count >= 5: + events.append(create_event('commIssue', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) + if self.CS.steer_error: events.append(create_event('steerUnavailable', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE, ET.PERMANENT])) if self.CS.steer_not_allowed: @@ -358,10 +356,11 @@ class CarInterface(object): # In GM, PCM faults out if ACC command overlaps user gas. enabled = c.enabled and not self.CS.user_gas_pressed - self.CC.update(self.sendcan, enabled, self.CS, self.frame, \ - c.actuators, - hud_v_cruise, c.hudControl.lanesVisible, \ - c.hudControl.leadVisible, \ - chime, chime_count) + can_sends = self.CC.update(enabled, self.CS, self.frame, \ + c.actuators, + hud_v_cruise, c.hudControl.lanesVisible, \ + c.hudControl.leadVisible, \ + chime, chime_count, c.hudControl.visualAlert) self.frame += 1 + return can_sends diff --git a/selfdrive/car/gm/radar_interface.py b/selfdrive/car/gm/radar_interface.py index e299ca6fc..7a8d9c471 100755 --- a/selfdrive/car/gm/radar_interface.py +++ b/selfdrive/car/gm/radar_interface.py @@ -19,7 +19,7 @@ NUM_SLOTS = 20 # messages that are present in DBC LAST_RADAR_MSG = RADAR_HEADER_MSG + NUM_SLOTS -def create_radard_can_parser(canbus, car_fingerprint): +def create_radar_can_parser(canbus, car_fingerprint): dbc_f = DBC[car_fingerprint]['radar'] if car_fingerprint in (CAR.VOLT, CAR.MALIBU, CAR.HOLDEN_ASTRA, CAR.ACADIA, CAR.CADILLAC_ATS): @@ -53,14 +53,14 @@ class RadarInterface(object): canbus = CanBus() print "Using %d as obstacle CAN bus ID" % canbus.obstacle - self.rcp = create_radard_can_parser(canbus, CP.carFingerprint) + self.rcp = create_radar_can_parser(canbus, CP.carFingerprint) context = zmq.Context() self.logcan = messaging.sub_sock(context, service_list['can'].port) def update(self): updated_messages = set() - ret = car.RadarState.new_message() + ret = car.RadarData.new_message() while 1: if self.rcp is None: @@ -68,7 +68,8 @@ class RadarInterface(object): return ret tm = int(sec_since_boot() * 1e9) - updated_messages.update(self.rcp.update(tm, True)) + _, vls = self.rcp.update(tm, True) + updated_messages.update(vls) if LAST_RADAR_MSG in updated_messages: break @@ -101,7 +102,7 @@ class RadarInterface(object): targetId = cpt['TrkObjectID'] currentTargets.add(targetId) if targetId not in self.pts: - self.pts[targetId] = car.RadarState.RadarPoint.new_message() + self.pts[targetId] = car.RadarData.RadarPoint.new_message() self.pts[targetId].trackId = targetId distance = cpt['TrkRange'] self.pts[targetId].dRel = distance # from front of car diff --git a/selfdrive/car/honda/carcontroller.py b/selfdrive/car/honda/carcontroller.py index a164f399f..bf7d158fc 100644 --- a/selfdrive/car/honda/carcontroller.py +++ b/selfdrive/car/honda/carcontroller.py @@ -1,6 +1,5 @@ from collections import namedtuple from common.realtime import sec_since_boot -from selfdrive.boardd.boardd import can_list_to_can_capnp from selfdrive.controls.lib.drive_helpers import rate_limit from common.numpy_fast import clip from selfdrive.car import create_gas_command @@ -75,26 +74,20 @@ HUDData = namedtuple("HUDData", class CarController(object): - def __init__(self, dbc_name, enable_camera=True): + def __init__(self, dbc_name): self.braking = False self.brake_steady = 0. self.brake_last = 0. self.apply_brake_last = 0 self.last_pump_ts = 0 - self.enable_camera = enable_camera self.packer = CANPacker(dbc_name) self.new_radar_config = False - def update(self, sendcan, enabled, CS, frame, actuators, \ + def update(self, enabled, CS, frame, actuators, \ pcm_speed, pcm_override, pcm_cancel_cmd, pcm_accel, \ hud_v_cruise, hud_show_lanes, hud_show_car, \ hud_alert, snd_beep, snd_chime): - """ Controls thread """ - - if not self.enable_camera: - return - # *** apply brake hysteresis *** brake, self.braking, self.brake_steady = actuator_hystereses(actuators.brake, self.braking, self.brake_steady, CS.v_ego, CS.CP.carFingerprint) @@ -161,7 +154,7 @@ class CarController(object): # Send dashboard UI commands. if (frame % 10) == 0: idx = (frame//10) % 4 - can_sends.extend(hondacan.create_ui_commands(self.packer, pcm_speed, hud, CS.CP.carFingerprint, idx)) + can_sends.extend(hondacan.create_ui_commands(self.packer, pcm_speed, hud, CS.CP.carFingerprint, CS.is_metric, idx)) if CS.CP.radarOffCan: # If using stock ACC, spam cancel command to kill gas when OP disengages. @@ -184,4 +177,4 @@ class CarController(object): # This prevents unexpected pedal range rescaling can_sends.append(create_gas_command(self.packer, apply_gas, idx)) - sendcan.send(can_list_to_can_capnp(can_sends, msgtype='sendcan')) + return can_sends diff --git a/selfdrive/car/honda/carstate.py b/selfdrive/car/honda/carstate.py index 72bca7e3e..f3374da57 100644 --- a/selfdrive/car/honda/carstate.py +++ b/selfdrive/car/honda/carstate.py @@ -46,7 +46,6 @@ def get_can_signals(CP): ("BRAKE_SWITCH", "POWERTRAIN_DATA", 0), ("CRUISE_BUTTONS", "SCM_BUTTONS", 0), ("ESP_DISABLED", "VSA_STATUS", 1), - ("HUD_LEAD", "ACC_HUD", 0), ("USER_BRAKE", "VSA_STATUS", 0), ("BRAKE_HOLD_ACTIVE", "VSA_STATUS", 0), ("STEER_STATUS", "STEER_STATUS", 5), @@ -124,6 +123,7 @@ def get_can_signals(CP): if CP.carFingerprint == CAR.CIVIC: signals += [("CAR_GAS", "GAS_PEDAL_2", 0), ("MAIN_ON", "SCM_FEEDBACK", 0), + ("IMPERIAL_UNIT", "HUD_SETTING", 0), ("EPB_STATE", "EPB_STATUS", 0)] elif CP.carFingerprint == CAR.ACURA_ILX: signals += [("CAR_GAS", "GAS_PEDAL_2", 0), @@ -152,7 +152,8 @@ def get_can_signals(CP): def get_can_parser(CP): signals, checks = get_can_signals(CP) - return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 0) + return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 0, timeout=100) + def get_cam_can_parser(CP): signals = [] @@ -164,7 +165,7 @@ def get_cam_can_parser(CP): cam_bus = 1 if CP.carFingerprint in HONDA_BOSCH else 2 - return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, cam_bus) + return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, cam_bus, timeout=100) class CarState(object): def __init__(self, CP): @@ -332,14 +333,15 @@ class CarState(object): self.user_brake = cp.vl["VSA_STATUS"]['USER_BRAKE'] self.pcm_acc_status = cp.vl["POWERTRAIN_DATA"]['ACC_STATUS'] - self.hud_lead = cp.vl["ACC_HUD"]['HUD_LEAD'] # Gets rid of Pedal Grinding noise when brake is pressed at slow speeds for some models - # TODO: this should be ok for all cars. Verify it. if self.CP.carFingerprint in (CAR.PILOT, CAR.PILOT_2019, CAR.RIDGELINE): if self.user_brake > 0.05: self.brake_pressed = 1 + # TODO: discover the CAN msg that has the imperial unit bit for all other cars + self.is_metric = not cp.vl["HUD_SETTING"]['IMPERIAL_UNIT'] if self.CP.carFingerprint in (CAR.CIVIC) else False + # carstate standalone tester if __name__ == '__main__': import zmq diff --git a/selfdrive/car/honda/hondacan.py b/selfdrive/car/honda/hondacan.py index 8f369feca..3955bfdcd 100644 --- a/selfdrive/car/honda/hondacan.py +++ b/selfdrive/car/honda/hondacan.py @@ -51,7 +51,7 @@ def create_steering_control(packer, apply_steer, lkas_active, car_fingerprint, i return packer.make_can_msg("STEERING_CONTROL", bus, values, idx) -def create_ui_commands(packer, pcm_speed, hud, car_fingerprint, idx): +def create_ui_commands(packer, pcm_speed, hud, car_fingerprint, is_metric, idx): commands = [] bus = 0 @@ -65,9 +65,10 @@ def create_ui_commands(packer, pcm_speed, hud, car_fingerprint, idx): 'CRUISE_SPEED': hud.v_cruise, 'ENABLE_MINI_CAR': hud.mini_car, 'HUD_LEAD': hud.car, - 'SET_ME_X03': 0x01 if car_fingerprint == CAR.ODYSSEY_CHN else 0x03, - 'SET_ME_X03_2': 0x02 if car_fingerprint == CAR.ODYSSEY_CHN else 0x03, - 'SET_ME_X01': 0x01, + 'HUD_DISTANCE': 3, # max distance setting on display + 'IMPERIAL_UNIT': int(not is_metric), + 'SET_ME_X01_2': 1, + 'SET_ME_X01': 1, } commands.append(packer.make_can_msg("ACC_HUD", 0, acc_hud_values, idx)) diff --git a/selfdrive/car/honda/interface.py b/selfdrive/car/honda/interface.py index 8c3a2bd76..b9b302d50 100755 --- a/selfdrive/car/honda/interface.py +++ b/selfdrive/car/honda/interface.py @@ -12,11 +12,6 @@ from selfdrive.car.honda.carstate import CarState, get_can_parser, get_cam_can_p from selfdrive.car.honda.values import CruiseButtons, CAR, HONDA_BOSCH, AUDIO_HUD, VISUAL_HUD from selfdrive.controls.lib.planner import _A_CRUISE_MAX_V_FOLLOWING -try: - from selfdrive.car.honda.carcontroller import CarController -except ImportError: - CarController = None - # msgs sent for steering controller by camera module on can 0. # those messages are mutually exclusive on CRV and non-CRV cars @@ -80,7 +75,7 @@ def get_compute_gb_acura(): class CarInterface(object): - def __init__(self, CP, sendcan=None): + def __init__(self, CP, CarController): self.CP = CP self.frame = 0 @@ -98,10 +93,9 @@ class CarInterface(object): self.CS = CarState(CP) self.VM = VehicleModel(CP) - # sending if read only is False - if sendcan is not None: - self.sendcan = sendcan - self.CC = CarController(self.cp.dbc_name, CP.enableCamera) + self.CC = None + if CarController is not None: + self.CC = CarController(self.cp.dbc_name) if self.CS.CP.carFingerprint == CAR.ACURA_ILX: self.compute_gb = get_compute_gb_acura() @@ -141,11 +135,12 @@ class CarInterface(object): return float(max(max_accel, a_target / A_ACC_MAX)) * min(speedLimiter, accelLimiter) @staticmethod - def get_params(candidate, fingerprint): + def get_params(candidate, fingerprint, vin=""): ret = car.CarParams.new_message() ret.carName = "honda" ret.carFingerprint = candidate + ret.carVin = vin if candidate in HONDA_BOSCH: ret.safetyModel = car.CarParams.SafetyModels.hondaBosch @@ -391,9 +386,9 @@ class CarInterface(object): def update(self, c): # ******************* do can recv ******************* canMonoTimes = [] - - self.cp.update(int(sec_since_boot() * 1e9), False) - self.cp_cam.update(int(sec_since_boot() * 1e9), False) + can_valid, _ = self.cp.update(int(sec_since_boot() * 1e9), True) + cam_valid, _ = self.cp_cam.update(int(sec_since_boot() * 1e9), False) + can_rcv_error = not can_valid or not cam_valid self.CS.update(self.cp, self.cp_cam) @@ -503,11 +498,12 @@ class CarInterface(object): events = [] if not self.CS.can_valid: self.can_invalid_count += 1 - if self.can_invalid_count >= 5: - events.append(create_event('commIssue', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) else: self.can_invalid_count = 0 + if can_rcv_error or self.can_invalid_count >= 5: + events.append(create_event('commIssue', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) + if not self.CS.cam_can_valid and self.CP.enableCamera: self.cam_can_invalid_count += 1 # wait 1.0s before throwing the alert to avoid it popping when you turn off the car @@ -612,17 +608,18 @@ class CarInterface(object): pcm_accel = int(clip(c.cruiseControl.accelOverride, 0, 1) * 0xc6) - self.CC.update(self.sendcan, c.enabled, self.CS, self.frame, - c.actuators, - c.cruiseControl.speedOverride, - c.cruiseControl.override, - c.cruiseControl.cancel, - pcm_accel, - hud_v_cruise, - c.hudControl.lanesVisible, - hud_show_car=c.hudControl.leadVisible, - hud_alert=hud_alert, - snd_beep=snd_beep, - snd_chime=snd_chime) + can_sends = self.CC.update(c.enabled, self.CS, self.frame, + c.actuators, + c.cruiseControl.speedOverride, + c.cruiseControl.override, + c.cruiseControl.cancel, + pcm_accel, + hud_v_cruise, + c.hudControl.lanesVisible, + hud_show_car=c.hudControl.leadVisible, + hud_alert=hud_alert, + snd_beep=snd_beep, + snd_chime=snd_chime) self.frame += 1 + return can_sends diff --git a/selfdrive/car/honda/radar_interface.py b/selfdrive/car/honda/radar_interface.py index 9977e763a..6b5d69208 100755 --- a/selfdrive/car/honda/radar_interface.py +++ b/selfdrive/car/honda/radar_interface.py @@ -43,7 +43,7 @@ class RadarInterface(object): canMonoTimes = [] updated_messages = set() - ret = car.RadarState.new_message() + ret = car.RadarData.new_message() # in Bosch radar and we are only steering for now, so sleep 0.05s to keep # radard at 20Hz and return no points @@ -53,7 +53,8 @@ class RadarInterface(object): while 1: tm = int(sec_since_boot() * 1e9) - updated_messages.update(self.rcp.update(tm, True)) + _, vls = self.rcp.update(tm, True) + updated_messages.update(vls) if 0x445 in updated_messages: break @@ -65,7 +66,7 @@ class RadarInterface(object): self.radar_wrong_config = cpt['RADAR_STATE'] == 0x69 elif cpt['LONG_DIST'] < 255: if ii not in self.pts or cpt['NEW_TRACK']: - self.pts[ii] = car.RadarState.RadarPoint.new_message() + self.pts[ii] = car.RadarData.RadarPoint.new_message() self.pts[ii].trackId = self.track_id self.track_id += 1 self.pts[ii].dRel = cpt['LONG_DIST'] # from front of car diff --git a/selfdrive/car/hyundai/carcontroller.py b/selfdrive/car/hyundai/carcontroller.py index 82dbc0aed..a1a688ff5 100644 --- a/selfdrive/car/hyundai/carcontroller.py +++ b/selfdrive/car/hyundai/carcontroller.py @@ -1,5 +1,4 @@ from selfdrive.car import apply_std_steer_torque_limits -from selfdrive.boardd.boardd import can_list_to_can_capnp from selfdrive.car.hyundai.hyundaican import create_lkas11, create_lkas12, \ create_1191, create_1156, \ create_clu11 @@ -18,23 +17,19 @@ class SteerLimitParams: STEER_DRIVER_FACTOR = 1 class CarController(object): - def __init__(self, dbc_name, car_fingerprint, enable_camera): + def __init__(self, dbc_name, car_fingerprint): self.apply_steer_last = 0 self.car_fingerprint = car_fingerprint self.lkas11_cnt = 0 self.cnt = 0 self.last_resume_cnt = 0 - self.enable_camera = enable_camera # True when giraffe switch 2 is low and we need to replace all the camera messages # otherwise we forward the camera msgs and we just replace the lkas cmd signals self.camera_disconnected = False self.packer = CANPacker(dbc_name) - def update(self, sendcan, enabled, CS, actuators, pcm_cancel_cmd, hud_alert): - - if not self.enable_camera: - return + def update(self, enabled, CS, actuators, pcm_cancel_cmd, hud_alert): ### Steering Torque apply_steer = actuators.steer * SteerLimitParams.STEER_MAX @@ -70,7 +65,6 @@ class CarController(object): self.last_resume_cnt = self.cnt can_sends.append(create_clu11(self.packer, CS.clu11, Buttons.RES_ACCEL)) - ### Send messages to canbus - sendcan.send(can_list_to_can_capnp(can_sends, msgtype='sendcan')) - self.cnt += 1 + + return can_sends diff --git a/selfdrive/car/hyundai/carstate.py b/selfdrive/car/hyundai/carstate.py index 041360f4b..6e5db74e5 100644 --- a/selfdrive/car/hyundai/carstate.py +++ b/selfdrive/car/hyundai/carstate.py @@ -93,7 +93,8 @@ def get_can_parser(CP): ("SAS11", 100) ] - return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 0) + return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 0, timeout=100) + def get_camera_parser(CP): @@ -118,7 +119,8 @@ def get_camera_parser(CP): checks = [] - return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 2) + return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 2, timeout=100) + class CarState(object): def __init__(self, CP): diff --git a/selfdrive/car/hyundai/interface.py b/selfdrive/car/hyundai/interface.py index cc5d95d06..75597bcb2 100644 --- a/selfdrive/car/hyundai/interface.py +++ b/selfdrive/car/hyundai/interface.py @@ -7,14 +7,9 @@ from selfdrive.controls.lib.vehicle_model import VehicleModel from selfdrive.car.hyundai.carstate import CarState, get_can_parser, get_camera_parser from selfdrive.car.hyundai.values import CAMERA_MSGS, CAR, get_hud_alerts, FEATURES -try: - from selfdrive.car.hyundai.carcontroller import CarController -except ImportError: - CarController = None - class CarInterface(object): - def __init__(self, CP, sendcan=None): + def __init__(self, CP, CarController): self.CP = CP self.VM = VehicleModel(CP) self.idx = 0 @@ -32,10 +27,9 @@ class CarInterface(object): self.cp = get_can_parser(CP) self.cp_cam = get_camera_parser(CP) - # sending if read only is False - if sendcan is not None: - self.sendcan = sendcan - self.CC = CarController(self.cp.dbc_name, CP.carFingerprint, CP.enableCamera) + self.CC = None + if CarController is not None: + self.CC = CarController(self.cp.dbc_name, CP.carFingerprint) @staticmethod def compute_gb(accel, speed): @@ -46,7 +40,7 @@ class CarInterface(object): return 1.0 @staticmethod - def get_params(candidate, fingerprint): + def get_params(candidate, fingerprint, vin=""): # kg of standard extra cargo to count for drive, gas, etc... std_cargo = 136 @@ -55,6 +49,7 @@ class CarInterface(object): ret.carName = "hyundai" ret.carFingerprint = candidate + ret.carVin = vin ret.radarOffCan = True ret.safetyModel = car.CarParams.SafetyModels.hyundai ret.enableCruise = True # stock acc @@ -179,8 +174,10 @@ class CarInterface(object): def update(self, c): # ******************* do can recv ******************* canMonoTimes = [] - self.cp.update(int(sec_since_boot() * 1e9), False) - self.cp_cam.update(int(sec_since_boot() * 1e9), False) + can_rcv_error = not self.cp.update(int(sec_since_boot() * 1e9), True) + cam_rcv_error = not self.cp_cam.update(int(sec_since_boot() * 1e9), False) + can_rcv_error = can_rcv_error or cam_rcv_error + self.CS.update(self.cp, self.cp_cam) # create message ret = car.CarState.new_message() @@ -261,10 +258,12 @@ class CarInterface(object): events = [] if not self.CS.can_valid: self.can_invalid_count += 1 - if self.can_invalid_count >= 5: - events.append(create_event('commIssue', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) else: self.can_invalid_count = 0 + + if can_rcv_error or self.can_invalid_count >= 5: + events.append(create_event('commIssue', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) + if not ret.gearShifter == 'drive': events.append(create_event('wrongGear', [ET.NO_ENTRY, ET.SOFT_DISABLE])) if ret.doorOpen: @@ -310,7 +309,7 @@ class CarInterface(object): hud_alert = get_hud_alerts(c.hudControl.visualAlert, c.hudControl.audibleAlert) - self.CC.update(self.sendcan, c.enabled, self.CS, c.actuators, - c.cruiseControl.cancel, hud_alert) + can_sends = self.CC.update(c.enabled, self.CS, c.actuators, + c.cruiseControl.cancel, hud_alert) - return False + return can_sends diff --git a/selfdrive/car/hyundai/radar_interface.py b/selfdrive/car/hyundai/radar_interface.py index 3e458df57..75256683d 100644 --- a/selfdrive/car/hyundai/radar_interface.py +++ b/selfdrive/car/hyundai/radar_interface.py @@ -11,7 +11,7 @@ class RadarInterface(object): def update(self): - ret = car.RadarState.new_message() + ret = car.RadarData.new_message() time.sleep(0.05) # radard runs on RI updates return ret diff --git a/selfdrive/car/mock/interface.py b/selfdrive/car/mock/interface.py index bf9b8a5e7..a14e4f0be 100755 --- a/selfdrive/car/mock/interface.py +++ b/selfdrive/car/mock/interface.py @@ -5,6 +5,7 @@ from selfdrive.config import Conversions as CV from selfdrive.services import service_list from selfdrive.swaglog import cloudlog import selfdrive.messaging as messaging +from common.realtime import Ratekeeper # mocked car interface to work with chffrplus TS = 0.01 # 100Hz @@ -14,9 +15,10 @@ LPG = 2 * 3.1415 * YAW_FR * TS / (1 + 2 * 3.1415 * YAW_FR * TS) class CarInterface(object): - def __init__(self, CP, sendcan=None): + def __init__(self, CP, CarController): self.CP = CP + self.CC = CarController cloudlog.debug("Using Mock Car Interface") context = zmq.Context() @@ -30,6 +32,8 @@ class CarInterface(object): self.yaw_rate = 0. self.yaw_rate_meas = 0. + self.rk = Ratekeeper(100, print_delay_threshold=2. / 1000) + @staticmethod def compute_gb(accel, speed): return accel @@ -39,7 +43,7 @@ class CarInterface(object): return 1.0 @staticmethod - def get_params(candidate, fingerprint): + def get_params(candidate, fingerprint, vin=""): ret = car.CarParams.new_message() @@ -79,6 +83,7 @@ class CarInterface(object): # returns a car.CarState def update(self, c): + self.rk.keep_time() # get basic data from phone and gps since CAN isn't connected sensors = messaging.recv_sock(self.sensor) @@ -120,4 +125,4 @@ class CarInterface(object): def apply(self, c): # in mock no carcontrols - return False + return [] diff --git a/selfdrive/car/mock/radar_interface.py b/selfdrive/car/mock/radar_interface.py index a99494b1a..437bb0538 100755 --- a/selfdrive/car/mock/radar_interface.py +++ b/selfdrive/car/mock/radar_interface.py @@ -11,7 +11,7 @@ class RadarInterface(object): def update(self): - ret = car.RadarState.new_message() + ret = car.RadarData.new_message() time.sleep(0.05) # radard runs on RI updates return ret diff --git a/selfdrive/car/subaru/carcontroller.py b/selfdrive/car/subaru/carcontroller.py index 9a098ea53..83dbbd7c5 100644 --- a/selfdrive/car/subaru/carcontroller.py +++ b/selfdrive/car/subaru/carcontroller.py @@ -1,6 +1,5 @@ #from common.numpy_fast import clip from common.realtime import sec_since_boot -from selfdrive.boardd.boardd import can_list_to_can_capnp from selfdrive.car import apply_std_steer_torque_limits from selfdrive.car.subaru import subarucan from selfdrive.car.subaru.values import CAR, DBC @@ -36,7 +35,7 @@ class CarController(object): print(DBC) self.packer = CANPacker(DBC[car_fingerprint]['pt']) - def update(self, sendcan, enabled, CS, frame, actuators, pcm_cancel_cmd, visual_alert, left_line, right_line): + def update(self, enabled, CS, frame, actuators, pcm_cancel_cmd, visual_alert, left_line, right_line): """ Controls thread """ P = self.params @@ -73,4 +72,4 @@ class CarController(object): can_sends.append(subarucan.create_es_lkas(self.packer, CS.es_lkas_msg, visual_alert, left_line, right_line)) self.es_lkas_cnt = CS.es_lkas_msg["Counter"] - sendcan.send(can_list_to_can_capnp(can_sends, msgtype='sendcan')) + return can_sends diff --git a/selfdrive/car/subaru/carstate.py b/selfdrive/car/subaru/carstate.py index 722b17118..0d5deec01 100644 --- a/selfdrive/car/subaru/carstate.py +++ b/selfdrive/car/subaru/carstate.py @@ -37,7 +37,8 @@ def get_powertrain_can_parser(CP): ("BodyInfo", 10), ] - return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 0) + return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 0, timeout=100) + def get_camera_can_parser(CP): signals = [ @@ -78,7 +79,8 @@ def get_camera_can_parser(CP): ("ES_DashStatus", 10), ] - return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 2) + return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 2, timeout=100) + class CarState(object): def __init__(self, CP): diff --git a/selfdrive/car/subaru/interface.py b/selfdrive/car/subaru/interface.py index 077f591a1..874745a66 100644 --- a/selfdrive/car/subaru/interface.py +++ b/selfdrive/car/subaru/interface.py @@ -7,14 +7,9 @@ from selfdrive.controls.lib.vehicle_model import VehicleModel from selfdrive.car.subaru.values import CAR from selfdrive.car.subaru.carstate import CarState, get_powertrain_can_parser, get_camera_can_parser -try: - from selfdrive.car.subaru.carcontroller import CarController -except ImportError: - CarController = None - class CarInterface(object): - def __init__(self, CP, sendcan=None): + def __init__(self, CP, CarController): self.CP = CP self.frame = 0 @@ -30,9 +25,8 @@ class CarInterface(object): self.gas_pressed_prev = False - # sending if read only is False - if sendcan is not None: - self.sendcan = sendcan + self.CC = None + if CarController is not None: self.CC = CarController(CP.carFingerprint) @staticmethod @@ -44,11 +38,12 @@ class CarInterface(object): return 1.0 @staticmethod - def get_params(candidate, fingerprint): + def get_params(candidate, fingerprint, vin=""): ret = car.CarParams.new_message() ret.carName = "subaru" ret.carFingerprint = candidate + ret.carVin = vin ret.safetyModel = car.CarParams.SafetyModels.subaru ret.enableCruise = True @@ -119,9 +114,10 @@ class CarInterface(object): # returns a car.CarState def update(self, c): + can_rcv_error = not self.pt_cp.update(int(sec_since_boot() * 1e9), True) + cam_rcv_error = not self.cam_cp.update(int(sec_since_boot() * 1e9), False) + can_rcv_error = can_rcv_error or cam_rcv_error - self.pt_cp.update(int(sec_since_boot() * 1e9), False) - self.cam_cp.update(int(sec_since_boot() * 1e9), False) self.CS.update(self.pt_cp, self.cam_cp) # create message @@ -183,11 +179,12 @@ class CarInterface(object): events = [] if not self.CS.can_valid: self.can_invalid_count += 1 - if self.can_invalid_count >= 5: - events.append(create_event('commIssue', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) else: self.can_invalid_count = 0 + if can_rcv_error or self.can_invalid_count >= 5: + events.append(create_event('commIssue', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) + if ret.seatbeltUnlatched: events.append(create_event('seatbeltNotLatched', [ET.NO_ENTRY, ET.SOFT_DISABLE])) @@ -216,7 +213,8 @@ class CarInterface(object): return ret.as_reader() def apply(self, c): - self.CC.update(self.sendcan, c.enabled, self.CS, self.frame, c.actuators, - c.cruiseControl.cancel, c.hudControl.visualAlert, - c.hudControl.leftLaneVisible, c.hudControl.rightLaneVisible) + can_sends = self.CC.update(c.enabled, self.CS, self.frame, c.actuators, + c.cruiseControl.cancel, c.hudControl.visualAlert, + c.hudControl.leftLaneVisible, c.hudControl.rightLaneVisible) self.frame += 1 + return can_sends diff --git a/selfdrive/car/subaru/radar_interface.py b/selfdrive/car/subaru/radar_interface.py index 3e458df57..75256683d 100644 --- a/selfdrive/car/subaru/radar_interface.py +++ b/selfdrive/car/subaru/radar_interface.py @@ -11,7 +11,7 @@ class RadarInterface(object): def update(self): - ret = car.RadarState.new_message() + ret = car.RadarData.new_message() time.sleep(0.05) # radard runs on RI updates return ret diff --git a/selfdrive/car/toyota/carcontroller.py b/selfdrive/car/toyota/carcontroller.py index 0bd5d9002..91bcb677a 100644 --- a/selfdrive/car/toyota/carcontroller.py +++ b/selfdrive/car/toyota/carcontroller.py @@ -1,6 +1,5 @@ from cereal import car from common.numpy_fast import clip, interp -from selfdrive.boardd.boardd import can_list_to_can_capnp from selfdrive.car import apply_toyota_steer_torque_limits from selfdrive.car import create_gas_command from selfdrive.car.toyota.toyotacan import make_can_msg, create_video_target,\ @@ -124,7 +123,7 @@ class CarController(object): self.packer = CANPacker(dbc_name) - def update(self, sendcan, enabled, CS, frame, actuators, + def update(self, enabled, CS, frame, actuators, pcm_cancel_cmd, hud_alert, audible_alert, forwarding_camera, left_line, right_line, lead, left_lane_depart, right_lane_depart): @@ -270,5 +269,4 @@ class CarController(object): can_sends.append(make_can_msg(addr, vl, bus, False)) - - sendcan.send(can_list_to_can_capnp(can_sends, msgtype='sendcan')) + return can_sends diff --git a/selfdrive/car/toyota/carstate.py b/selfdrive/car/toyota/carstate.py index 88471b61a..cdb735d4f 100644 --- a/selfdrive/car/toyota/carstate.py +++ b/selfdrive/car/toyota/carstate.py @@ -68,7 +68,7 @@ def get_can_parser(CP): signals.append(("INTERCEPTOR_GAS", "GAS_SENSOR", 0)) checks.append(("GAS_SENSOR", 50)) - return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 0) + return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 0, timeout=100) def get_cam_can_parser(CP): @@ -78,7 +78,7 @@ def get_cam_can_parser(CP): # use steering message to check if panda is connected to frc checks = [("STEERING_LKA", 42)] - return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 2) + return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 2, timeout=100) class CarState(object): diff --git a/selfdrive/car/toyota/interface.py b/selfdrive/car/toyota/interface.py index ea5b748d5..71ace4c1f 100755 --- a/selfdrive/car/toyota/interface.py +++ b/selfdrive/car/toyota/interface.py @@ -8,14 +8,9 @@ from selfdrive.car.toyota.carstate import CarState, get_can_parser, get_cam_can_ from selfdrive.car.toyota.values import ECU, check_ecu_msgs, CAR, NO_STOP_TIMER_CAR from selfdrive.swaglog import cloudlog -try: - from selfdrive.car.toyota.carcontroller import CarController -except ImportError: - CarController = None - class CarInterface(object): - def __init__(self, CP, sendcan=None): + def __init__(self, CP, CarController): self.CP = CP self.VM = VehicleModel(CP) @@ -34,9 +29,8 @@ class CarInterface(object): self.forwarding_camera = False - # sending if read only is False - if sendcan is not None: - self.sendcan = sendcan + self.CC = None + if CarController is not None: self.CC = CarController(self.cp.dbc_name, CP.carFingerprint, CP.enableCamera, CP.enableDsu, CP.enableApgs) @staticmethod @@ -48,7 +42,7 @@ class CarInterface(object): return 1.0 @staticmethod - def get_params(candidate, fingerprint): + def get_params(candidate, fingerprint, vin=""): # kg of standard extra cargo to count for drive, gas, etc... std_cargo = 136 @@ -57,6 +51,7 @@ class CarInterface(object): ret.carName = "toyota" ret.carFingerprint = candidate + ret.carVin = vin ret.safetyModel = car.CarParams.SafetyModels.toyota @@ -256,7 +251,8 @@ class CarInterface(object): # ******************* do can recv ******************* canMonoTimes = [] - self.cp.update(int(sec_since_boot() * 1e9), False) + can_valid, _ = self.cp.update(int(sec_since_boot() * 1e9), True) + can_rcv_error = not can_valid # run the cam can update for 10s as we just need to know if the camera is alive if self.frame < 1000: @@ -341,11 +337,12 @@ class CarInterface(object): events = [] if not self.CS.can_valid: self.can_invalid_count += 1 - if self.can_invalid_count >= 5: - events.append(create_event('commIssue', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) else: self.can_invalid_count = 0 + if can_rcv_error or self.can_invalid_count >= 5: + events.append(create_event('commIssue', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) + if self.CS.cam_can_valid: self.cam_can_valid_count += 1 if self.cam_can_valid_count >= 5: @@ -403,11 +400,11 @@ class CarInterface(object): # to be called @ 100hz def apply(self, c): - self.CC.update(self.sendcan, c.enabled, self.CS, self.frame, - c.actuators, c.cruiseControl.cancel, c.hudControl.visualAlert, - c.hudControl.audibleAlert, self.forwarding_camera, - c.hudControl.leftLaneVisible, c.hudControl.rightLaneVisible, c.hudControl.leadVisible, - c.hudControl.leftLaneDepart, c.hudControl.rightLaneDepart) + can_sends = self.CC.update(c.enabled, self.CS, self.frame, + c.actuators, c.cruiseControl.cancel, c.hudControl.visualAlert, + c.hudControl.audibleAlert, self.forwarding_camera, + c.hudControl.leftLaneVisible, c.hudControl.rightLaneVisible, c.hudControl.leadVisible, + c.hudControl.leftLaneDepart, c.hudControl.rightLaneDepart) self.frame += 1 - return False + return can_sends diff --git a/selfdrive/car/toyota/radar_interface.py b/selfdrive/car/toyota/radar_interface.py index fc6f3e523..b8628c5bb 100755 --- a/selfdrive/car/toyota/radar_interface.py +++ b/selfdrive/car/toyota/radar_interface.py @@ -9,7 +9,7 @@ from selfdrive.services import service_list import selfdrive.messaging as messaging from selfdrive.car.toyota.values import NO_DSU_CAR, DBC, TSSP2_CAR -def _create_radard_can_parser(car_fingerprint): +def _create_radar_can_parser(car_fingerprint): dbc_f = DBC[car_fingerprint]['radar'] if car_fingerprint in TSSP2_CAR: @@ -48,7 +48,7 @@ class RadarInterface(object): self.valid_cnt = {key: 0 for key in self.RADAR_A_MSGS} - self.rcp = _create_radard_can_parser(CP.carFingerprint) + self.rcp = _create_radar_can_parser(CP.carFingerprint) self.no_dsu_car = CP.carFingerprint in NO_DSU_CAR context = zmq.Context() @@ -56,7 +56,7 @@ class RadarInterface(object): def update(self): - ret = car.RadarState.new_message() + ret = car.RadarData.new_message() if self.no_dsu_car: # TODO: make a adas dbc file for dsu-less models @@ -67,7 +67,8 @@ class RadarInterface(object): updated_messages = set() while 1: tm = int(sec_since_boot() * 1e9) - updated_messages.update(self.rcp.update(tm, True)) + _, vls = self.rcp.update(tm, True) + updated_messages.update(vls) if self.RADAR_B_MSGS[-1] in updated_messages: break @@ -94,7 +95,7 @@ class RadarInterface(object): # radar point only valid if it's a valid measurement and score is above 50 if cpt['VALID'] or (score > 50 and cpt['LONG_DIST'] < 255 and self.valid_cnt[ii] > 0): if ii not in self.pts or cpt['NEW_TRACK']: - self.pts[ii] = car.RadarState.RadarPoint.new_message() + self.pts[ii] = car.RadarData.RadarPoint.new_message() self.pts[ii].trackId = self.track_id self.track_id += 1 self.pts[ii].dRel = cpt['LONG_DIST'] # from front of car diff --git a/selfdrive/car/toyota/values.py b/selfdrive/car/toyota/values.py index d1da58792..dc8298192 100644 --- a/selfdrive/car/toyota/values.py +++ b/selfdrive/car/toyota/values.py @@ -133,10 +133,18 @@ FINGERPRINTS = { #SL { 36: 8, 37: 8, 166: 8, 170: 8, 180: 8, 295: 8, 296: 8, 426: 6, 452: 8, 466: 8, 467: 8, 550: 8, 552: 4, 560: 7, 562: 6, 581: 5, 608: 8, 610: 8, 643: 7, 713: 8, 728: 8, 740: 5, 761: 8, 764: 8, 800: 8, 810: 2, 812: 8, 818: 8, 824: 8, 829: 2, 830: 7, 835: 8, 836: 8, 869: 7, 870: 7, 871: 2, 888: 8, 889: 8, 898: 8, 900: 6, 902: 6, 905: 8, 913: 8, 918: 8, 921: 8, 933: 8, 934: 8, 935: 8, 944: 8, 945: 8, 950: 8, 951: 8, 953: 8, 955: 8, 956: 8, 971: 7, 975: 5, 993: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1002: 8, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1044: 8, 1056: 8, 1057: 8, 1059: 1, 1071: 8, 1076: 8, 1077: 8, 1084: 8, 1085: 8, 1086: 8, 1114: 8, 1132: 8, 1161: 8, 1162: 8, 1163: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1228: 8, 1235: 8, 1237: 8, 1264: 8, 1279: 8, 1541: 8, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1595: 8, 1745: 8, 1779: 8, 1786: 8, 1787: 8, 1788: 8, 1789: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 + }, + #XLE + { + 36: 8, 37: 8, 166: 8, 170: 8, 180: 8, 295: 8, 296: 8, 426: 6, 452: 8, 466: 8, 467: 8, 550: 8, 552: 4, 560: 7, 562: 6, 581: 5, 608: 8, 610: 8, 643: 7, 658: 8, 713: 8, 728: 8, 740: 5, 761: 8, 764: 8, 800: 8, 810: 2, 812: 8, 814: 8, 818: 8, 824: 8, 829: 2, 830: 7, 835: 8, 836: 8, 869: 7, 870: 7, 871: 2, 888: 8, 889: 8, 898: 8, 900: 6, 902: 6, 905: 8, 918: 8, 921: 8, 933: 8, 934: 8, 935: 8, 944: 8, 945: 8, 950: 8, 951: 8, 953: 8, 955: 8, 956: 8, 971: 7, 975: 5, 983: 8, 984: 8, 993: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1002: 8, 1011: 8, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1044: 8, 1056: 8, 1057: 8, 1059: 1, 1071: 8, 1076: 8, 1077: 8, 1082: 8, 1084: 8, 1085: 8, 1086: 8, 1114: 8, 1132: 8, 1161: 8, 1162: 8, 1163: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1228: 8, 1235: 8, 1237: 8, 1264: 8, 1279: 8, 1541: 8, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1595: 8, 1745: 8, 1779: 8, 1786: 8, 1787: 8, 1788: 8, 1789: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 }], CAR.HIGHLANDER: [{ 36: 8, 37: 8, 114: 5, 119: 6, 120: 4, 170: 8, 180: 8, 186: 4, 238: 4, 355: 5, 426: 6, 452: 8, 464: 8, 466: 8, 467: 8, 544: 4, 545: 5, 550: 8, 552: 4, 608: 8, 610: 5, 643: 7, 705: 8, 725: 2, 740: 5, 800: 8, 835: 8, 836: 8, 849: 4, 869: 7, 870: 7, 871: 2, 896: 8, 900: 6, 902: 6, 905: 8, 911: 8, 916: 3, 921: 8, 922: 8, 933: 8, 944: 8, 945: 8, 951: 8, 955: 8, 956: 8, 979: 2, 998: 5, 999: 7, 1000: 8, 1001: 8, 1008: 2, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1043: 8, 1044: 8, 1056: 8, 1059: 1, 1114: 8, 1161: 8, 1162: 8, 1163: 8, 1176: 8, 1177: 8, 1178: 8, 1179: 8, 1180: 8, 1181: 8, 1182: 8, 1183: 8, 1189: 8, 1190: 8, 1191: 8, 1192: 8, 1196: 8, 1197: 8, 1198: 8, 1199: 8, 1206: 8, 1207: 8, 1212: 8, 1227: 8, 1235: 8, 1237: 8, 1279: 8, 1408: 8, 1409: 8, 1410: 8, 1552: 8, 1553: 8, 1554: 8, 1556: 8, 1557: 8, 1561: 8, 1562: 8, 1568: 8, 1569: 8, 1570: 8, 1571: 8, 1572: 8, 1584: 8, 1589: 8, 1592: 8, 1593: 8, 1595: 8, 1599: 8, 1656: 8, 1666: 8, 1667: 8, 1728: 8, 1745: 8, 1779: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 }, + # 2019 Highlander XLE + { + 36: 8, 37: 8, 114: 5, 119: 6, 120: 4, 170: 8, 180: 8, 186: 4, 238: 4, 355: 5, 426: 6, 452: 8, 464: 8, 466: 8, 467: 8, 544: 4, 545: 5, 550: 8, 552: 4, 608: 8, 610: 5, 643: 7, 705: 8, 725: 2, 740: 5, 800: 8, 835: 8, 836: 8, 849: 4, 869: 7, 870: 7, 871: 2, 896: 8, 900: 6, 902: 6, 905: 8, 911: 8, 916: 3, 921: 8, 922: 8, 933: 8, 944: 8, 945: 8, 951: 8, 955: 8, 956: 8, 979: 2, 992: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1008: 2, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1043: 8, 1044: 8, 1056: 8, 1059: 1, 1076: 8, 1077: 8, 1114: 8, 1161: 8, 1162: 8, 1163: 8, 1176: 8, 1177: 8, 1178: 8, 1179: 8, 1180: 8, 1181: 8, 1182: 8, 1183: 8, 1189: 8, 1190: 8, 1191: 8, 1192: 8, 1196: 8, 1197: 8, 1198: 8, 1199: 8, 1206: 8, 1207: 8, 1212: 8, 1227: 8, 1235: 8, 1237: 8, 1279: 8, 1408: 8, 1409: 8, 1410: 8, 1552: 8, 1553: 8, 1554: 8, 1556: 8, 1557: 8, 1561: 8, 1562: 8, 1568: 8, 1569: 8, 1570: 8, 1571: 8, 1572: 8, 1584: 8, 1589: 8, 1592: 8, 1593: 8, 1595: 8, 1599: 8, 1656: 8, 1728: 8, 1745: 8, 1779: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 + }, # 2017 Highlander Limited { 36: 8, 37: 8, 114: 5, 119: 6, 120: 4, 170: 8, 180: 8, 186: 4, 238: 4, 355: 5, 426: 6, 452: 8, 464: 8, 466: 8, 467: 8, 544: 4, 545: 5, 550: 8, 552: 4, 608: 8, 610: 5, 643: 7, 705: 8, 725: 2, 740: 5, 800: 8, 835: 8, 836: 8, 849: 4, 869: 7, 870: 7, 871: 2, 896: 8, 900: 6, 902: 6, 905: 8, 911: 8, 916: 3, 918: 7, 921: 8, 922: 8, 933: 8, 944: 8, 945: 8, 951: 8, 955: 8, 956: 8, 979: 2, 998: 5, 999: 7, 1000: 8, 1001: 8, 1005: 2, 1008: 2, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1043: 8, 1044: 8, 1056: 8, 1059: 1, 1114: 8, 1161: 8, 1162: 8, 1163: 8, 1176: 8, 1177: 8, 1178: 8, 1179: 8, 1180: 8, 1181: 8, 1182: 8, 1183: 8, 1189: 8, 1190: 8, 1191: 8, 1192: 8, 1196: 8, 1197: 8, 1198: 8, 1199: 8, 1206: 8, 1207: 8, 1212: 8, 1227: 8, 1235: 8, 1237: 8, 1264: 8, 1279: 8, 1408: 8, 1409: 8, 1410: 8, 1552: 8, 1553: 8, 1554: 8, 1556: 8, 1557: 8, 1561: 8, 1562: 8, 1568: 8, 1569: 8, 1570: 8, 1571: 8, 1572: 8, 1584: 8, 1589: 8, 1592: 8, 1593: 8, 1595: 8, 1599: 8, 1656: 8, 1728: 8, 1745: 8, 1779: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 @@ -152,12 +160,12 @@ FINGERPRINTS = { { 36: 8, 37: 8, 170: 8, 180: 8, 186: 4, 355: 5, 401: 8, 426: 6, 452: 8, 464: 8, 466: 8, 467: 8, 544: 4, 550: 8, 552: 4, 562: 6, 565: 8, 608: 8, 610: 8, 643: 7, 705: 8, 728: 8, 740: 5, 742: 8, 743: 8, 761: 8, 764: 8, 765: 8, 800: 8, 810: 2, 812: 8, 824: 8, 829: 2, 830: 7, 835: 8, 836: 8, 865: 8, 869: 7, 870: 7, 871: 2, 877: 8, 881: 8, 882: 8, 885: 8, 896: 8, 898: 8, 900: 6, 902: 6, 905: 8, 921: 8, 933: 8, 934: 8, 935: 8, 944: 8, 945: 8, 951: 8, 955: 8, 956: 8, 976: 1, 998: 5, 999: 7, 1000: 8, 1001: 8, 1002: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1044: 8, 1056: 8, 1059: 1, 1063: 8, 1076: 8, 1077: 8,1114: 8, 1161: 8, 1162: 8, 1163: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1172: 8, 1235: 8, 1279: 8, 1541: 8, 1552: 8, 1553:8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1592: 8, 1594: 8, 1595: 8, 1649: 8, 1745: 8, 1775: 8, 1779: 8, 1786: 8, 1787: 8, 1788: 8, 1789: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 }, - # XLE + # XLE and AWD { - 36: 8, 37: 8, 170: 8, 180: 8, 186: 4, 401: 8, 426: 6, 452: 8, 464: 8, 466: 8, 467: 8, 544: 4, 550: 8, 552: 4, 562: 6, 565: 8, 608: 8, 610: 8, 643: 7, 705: 8, 728: 8, 740: 5, 742: 8, 743: 8, 761: 8, 764: 8, 765: 8, 800: 8, 810: 2, 812: 8, 824: 8, 829: 2, 830: 7, 835: 8, 836: 8, 865: 8, 869: 7, 870: 7, 871: 2, 877: 8, 881: 8, 882: 8, 885: 8, 896: 8, 898: 8, 900: 6, 902: 6, 905: 8, 921: 8, 933: 8, 934: 8, 935: 8, 944: 8, 945: 8, 951: 8, 955: 8, 956: 8, 976: 1, 998: 5, 999: 7, 1000: 8, 1001: 8, 1002: 8, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1044: 8, 1056: 8, 1059: 1, 1063: 8, 1076: 8, 1077: 8, 1114: 8, 1161: 8, 1162: 8, 1163: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1172: 8, 1235: 8, 1237: 8, 1279: 8, 1541: 8, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1592: 8, 1594: 8, 1595: 8, 1649: 8, 1745: 8, 1775: 8, 1779: 8, 1786: 8, 1787: 8, 1788: 8, 1789: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 + 36: 8, 37: 8, 170: 8, 180: 8, 186: 4, 401: 8, 426: 6, 452: 8, 464: 8, 466: 8, 467: 8, 544: 4, 550: 8, 552: 4, 562: 6, 565: 8, 608: 8, 610: 8, 643: 7, 658: 8, 705: 8, 728: 8, 740: 5, 742: 8, 743: 8, 761: 8, 764: 8, 765: 8, 800: 8, 810: 2, 812: 8, 814: 8, 818: 8, 822: 8, 824: 8, 829: 2, 830: 7, 835: 8, 836: 8, 865: 8, 869: 7, 870: 7, 871: 2, 877: 8, 881: 8, 882: 8, 885: 8, 889: 8, 891: 8, 896: 8, 898: 8, 900: 6, 902: 6, 905: 8, 918: 8, 921: 8, 933: 8, 934: 8, 935: 8, 944: 8, 945: 8, 951: 8, 955: 8, 956: 8, 976: 1, 987: 8, 998: 5, 999: 7, 1000: 8, 1001: 8, 1002: 8, 1014: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1044: 8, 1056: 8, 1059: 1, 1063: 8, 1076: 8, 1077: 8, 1082: 8, 1084: 8, 1085: 8, 1086: 8, 1114: 8, 1132: 8, 1161: 8, 1162: 8, 1163: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1172: 8, 1228: 8, 1235: 8, 1237: 8, 1263: 8, 1264: 8, 1279: 8, 1541: 8, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1592: 8, 1594: 8, 1595: 8, 1649: 8, 1696: 8, 1745: 8, 1775: 8, 1779: 8, 1786: 8, 1787: 8, 1788: 8, 1789: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 }], CAR.COROLLA_HATCH: [{ - 36: 8, 37: 8, 114: 5, 170: 8, 180: 8, 186: 4, 401: 8, 426: 6, 452: 8 , 464: 8, 466: 8, 467: 8, 544: 4, 550: 8, 552: 4, 562: 6, 608: 8, 610: 8, 643: 7 , 705: 8, 728: 8, 740: 5, 742: 8, 743: 8, 761: 8, 764: 8, 765: 8, 800: 8, 810: 2, 812: 8, 824: 8, 829: 2, 830: 7, 835: 8, 836: 8, 865: 8, 869: 7, 870: 7, 871: 2, 877: 8, 881: 8, 896: 8, 898: 8, 900: 6, 902: 6, 905: 8, 921: 8, 933: 8, 934: 8, 935: 8, 944: 8, 945: 8, 951: 8, 955: 8, 956: 8, 976: 1, 998: 5, 999: 7, 1000:8, 1001: 8, 1002: 8, 1017:8, 1020: 8, 1041: 8, 1042: 8, 1044: 8, 1056: 8, 1059:1, 1076: 8, 1077: 8, 1114: 8, 1161: 8, 1162: 8, 1163: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1172: 8, 1235: 8, 1279: 8, 1541: 8, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1592: 8, 1595: 8, 1745: 8, 1775: 8, 1779: 8, 1786: 8, 1787: 8, 1788: 8, 1789: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 + 36: 8, 37: 8, 114: 5, 170: 8, 180: 8, 186: 4, 401: 8, 426: 6, 452: 8, 464: 8, 466: 8, 467: 8, 544: 4, 550: 8, 552: 4, 562: 6, 608: 8, 610: 8, 643: 7, 705: 8, 728: 8, 740: 5, 742: 8, 743: 8, 761: 8, 764: 8, 765: 8, 800: 8, 810: 2, 812: 8, 824: 8, 829: 2, 830: 7, 835: 8, 836: 8, 865: 8, 869: 7, 870: 7, 871: 2, 877: 8, 881: 8, 896: 8, 898: 8, 900: 6, 902: 6, 905: 8, 921: 8, 933: 8, 934: 8, 935: 8, 944: 8, 945: 8, 951: 8, 955: 8, 956: 8, 976: 1, 998: 5, 999: 7, 1000: 8, 1001: 8, 1002: 8, 1017: 8, 1020: 8, 1041: 8, 1042: 8, 1044: 8, 1056: 8, 1059: 1, 1076: 8, 1077: 8, 1114: 8, 1161: 8, 1162: 8, 1163: 8, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1172: 8, 1235: 8, 1279: 8, 1541: 8, 1552: 8, 1553: 8, 1556: 8, 1557: 8, 1568: 8, 1570: 8, 1571: 8, 1572: 8, 1592: 8, 1595: 8, 1649: 8, 1745: 8, 1775: 8, 1779: 8, 1786: 8, 1787: 8, 1788: 8, 1789: 8, 1904: 8, 1912: 8, 1990: 8, 1998: 8 }] } diff --git a/selfdrive/common/messaging.h b/selfdrive/common/messaging.h new file mode 100644 index 000000000..725129508 --- /dev/null +++ b/selfdrive/common/messaging.h @@ -0,0 +1,15 @@ +// the c version of selfdrive/messaging.py + +#include + +// TODO: refactor to take in service instead of endpoint? +void *sub_sock(void *ctx, const char *endpoint) { + void* sock = zmq_socket(ctx, ZMQ_SUB); + assert(sock); + zmq_setsockopt(sock, ZMQ_SUBSCRIBE, "", 0); + int reconnect_ivl = 500; + zmq_setsockopt(sock, ZMQ_RECONNECT_IVL_MAX, &reconnect_ivl, sizeof(reconnect_ivl)); + zmq_connect(sock, endpoint); + return sock; +} + diff --git a/selfdrive/common/version.h b/selfdrive/common/version.h index f2f73bbe0..b925f4152 100644 --- a/selfdrive/common/version.h +++ b/selfdrive/common/version.h @@ -1 +1 @@ -#define COMMA_VERSION "0.5.12-release" +#define COMMA_VERSION "0.5.13-release" diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index bbc90976b..8e27c7c3b 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -12,7 +12,8 @@ from common.params import Params import selfdrive.messaging as messaging from selfdrive.config import Conversions as CV from selfdrive.services import service_list -from selfdrive.car.car_helpers import get_car +from selfdrive.boardd.boardd import can_list_to_can_capnp +from selfdrive.car.car_helpers import get_car, get_startup_alert from selfdrive.controls.lib.model_parser import CAMERA_OFFSET from selfdrive.controls.lib.drive_helpers import learn_angle_model_bias, \ get_events, \ @@ -30,7 +31,7 @@ from selfdrive.controls.lib.planner import _DT_MPC from selfdrive.locationd.calibration_helpers import Calibration, Filter ThermalStatus = log.ThermalData.ThermalStatus -State = log.Live100Data.ControlState +State = log.ControlsState.OpenpilotState def isActive(state): @@ -209,7 +210,7 @@ def state_transition(CS, CP, state, events, soft_disable_timer, v_cruise_kph, AM def state_control(rcv_times, plan, path_plan, CS, CP, state, events, v_cruise_kph, v_cruise_kph_last, AM, rk, - driver_status, LaC, LoC, VM, angle_model_bias, passive, is_metric, cal_perc): + driver_status, LaC, LoC, VM, angle_model_bias, read_only, is_metric, cal_perc): """Given the state, this function returns an actuators packet""" actuators = car.CarControl.Actuators.new_message() @@ -288,15 +289,15 @@ def state_control(rcv_times, plan, path_plan, CS, CP, state, events, v_cruise_kp def data_send(plan, path_plan, CS, CI, CP, VM, state, events, actuators, v_cruise_kph, rk, carstate, - carcontrol, live100, AM, driver_status, - LaC, LoC, angle_model_bias, passive, start_time, v_acc, a_acc, lac_log): - """Send actuators and hud commands to the car, send live100 and MPC logging""" + carcontrol, controlsstate, sendcan, AM, driver_status, + LaC, LoC, angle_model_bias, read_only, start_time, v_acc, a_acc, lac_log): + """Send actuators and hud commands to the car, send controlsstate and MPC logging""" plan_ts = plan.logMonoTime plan = plan.plan CC = car.CarControl.new_message() - if not passive: + if not read_only: CC.enabled = isEnabled(state) CC.actuators = actuators @@ -331,14 +332,15 @@ def data_send(plan, path_plan, CS, CI, CP, VM, state, events, actuators, v_cruis CC.hudControl.audibleAlert = AM.audible_alert # send car controls over can - CI.apply(CC) + can_sends = CI.apply(CC) + sendcan.send(can_list_to_can_capnp(can_sends, msgtype='sendcan')) force_decel = driver_status.awareness < 0. - # live100 + # controlsState dat = messaging.new_message() - dat.init('live100') - dat.live100 = { + dat.init('controlsState') + dat.controlsState = { "alertText1": AM.alert_text_1, "alertText2": AM.alert_text_2, "alertSize": AM.alert_size, @@ -381,10 +383,10 @@ def data_send(plan, path_plan, CS, CI, CP, VM, state, events, actuators, v_cruis } if CP.lateralTuning.which() == 'pid': - dat.live100.lateralControlState.pidState = lac_log + dat.controlsState.lateralControlState.pidState = lac_log else: - dat.live100.lateralControlState.indiState = lac_log - live100.send(dat.to_bytes()) + dat.controlsState.lateralControlState.indiState = lac_log + controlsstate.send(dat.to_bytes()) # carState cs_send = messaging.new_message() @@ -402,7 +404,7 @@ def data_send(plan, path_plan, CS, CI, CP, VM, state, events, actuators, v_cruis return CC -def controlsd_thread(gctx=None, rate=100): +def controlsd_thread(gctx=None): gc.disable() # start the loop @@ -412,18 +414,14 @@ def controlsd_thread(gctx=None, rate=100): params = Params() # Pub Sockets - live100 = messaging.pub_sock(context, service_list['live100'].port) + controlsstate = messaging.pub_sock(context, service_list['controlsState'].port) carstate = messaging.pub_sock(context, service_list['carState'].port) carcontrol = messaging.pub_sock(context, service_list['carControl'].port) is_metric = params.get("IsMetric") == "1" passive = params.get("Passive") != "0" - # No sendcan if passive - if not passive: - sendcan = messaging.pub_sock(context, service_list['sendcan'].port) - else: - sendcan = None + sendcan = messaging.pub_sock(context, service_list['sendcan'].port) # Sub sockets poller = zmq.Poller() @@ -436,18 +434,18 @@ def controlsd_thread(gctx=None, rate=100): logcan = messaging.sub_sock(context, service_list['can'].port) CC = car.CarControl.new_message() - CI, CP = get_car(logcan, sendcan, 1.0 if passive else None) + CI, CP = get_car(logcan, sendcan) + AM = AlertManager() - if CI is None: - raise Exception("unsupported car") + car_recognized = CP.carName != 'mock' + # If stock camera is disconnected, we loaded car controls and it's not chffrplus + controller_available = CP.enableCamera and CI.CC is not None and not passive + read_only = not car_recognized or not controller_available + if read_only: + CP.safetyModel = car.CarParams.SafetyModels.elm327 # diagnostic only - # if stock camera is connected, then force passive behavior - if not CP.enableCamera: - passive = True - sendcan = None - - if passive: - CP.safetyModel = car.CarParams.SafetyModels.noOutput + startup_alert = get_startup_alert(car_recognized, controller_available) + AM.add(startup_alert, False) LoC = LongControl(CP, CI.compute_gb) VM = VehicleModel(CP) @@ -457,12 +455,8 @@ def controlsd_thread(gctx=None, rate=100): else: LaC = LatControlINDI(CP) - AM = AlertManager() driver_status = DriverStatus() - if not passive: - AM.add("startup", False) - # Write CarParams for radard and boardd safety mode params.put("CarParams", CP.to_bytes()) params.put("LongitudinalControl", "1" if CP.openpilotLongitudinalControl else "0") @@ -484,8 +478,10 @@ def controlsd_thread(gctx=None, rate=100): plan.init('plan') path_plan = messaging.new_message() path_plan.init('pathPlan') + path_plan.pathPlan.sensorValid = True - rk = Ratekeeper(rate, print_delay_threshold=2. / 1000) + # controlsd is driven by can recv, expected at 100Hz + rk = Ratekeeper(100, print_delay_threshold=None) controls_params = params.get("ControlsParams") # Read angle offset from previous drive @@ -516,6 +512,8 @@ def controlsd_thread(gctx=None, rate=100): if not path_plan.pathPlan.valid or plan_age > 0.5 or path_plan_age > 0.5: events.append(create_event('plannerError', [ET.NO_ENTRY, ET.SOFT_DISABLE])) + if not path_plan.pathPlan.sensorValid: + events.append(create_event('sensorDataInvalid', [ET.NO_ENTRY, ET.PERMANENT])) if not path_plan.pathPlan.paramsValid: events.append(create_event('vehicleModelInvalid', [ET.WARNING])) if not path_plan.pathPlan.modelValid: @@ -529,7 +527,7 @@ def controlsd_thread(gctx=None, rate=100): if CS.brakePressed and plan.plan.vTargetFuture >= STARTING_TARGET_SPEED and not CP.radarOffCan and CS.vEgo < 0.3: events.append(create_event('noTarget', [ET.NO_ENTRY, ET.IMMEDIATE_DISABLE])) - if not passive: + if not read_only: # update control state state, soft_disable_timer, v_cruise_kph, v_cruise_kph_last = \ state_transition(CS, CP, state, events, soft_disable_timer, v_cruise_kph, AM) @@ -539,21 +537,21 @@ def controlsd_thread(gctx=None, rate=100): actuators, v_cruise_kph, driver_status, angle_model_bias, v_acc, a_acc, lac_log = \ state_control(rcv_times, plan.plan, path_plan.pathPlan, CS, CP, state, events, v_cruise_kph, v_cruise_kph_last, AM, rk, driver_status, - LaC, LoC, VM, angle_model_bias, passive, is_metric, cal_perc) + LaC, LoC, VM, angle_model_bias, read_only, is_metric, cal_perc) prof.checkpoint("State Control") # Publish data CC = data_send(plan, path_plan, CS, CI, CP, VM, state, events, actuators, v_cruise_kph, rk, carstate, carcontrol, - live100, AM, driver_status, LaC, LoC, angle_model_bias, passive, start_time, v_acc, a_acc, lac_log) + controlsstate, sendcan, AM, driver_status, LaC, LoC, angle_model_bias, read_only, start_time, v_acc, a_acc, lac_log) prof.checkpoint("Sent") - rk.keep_time() # Run at 100Hz + rk.monitor_time() prof.display() def main(gctx=None): - controlsd_thread(gctx, 100) + controlsd_thread(gctx) if __name__ == "__main__": diff --git a/selfdrive/controls/lib/alertmanager.py b/selfdrive/controls/lib/alertmanager.py index 5884e9870..5ce2bfac1 100644 --- a/selfdrive/controls/lib/alertmanager.py +++ b/selfdrive/controls/lib/alertmanager.py @@ -5,8 +5,8 @@ from common.realtime import sec_since_boot import copy -AlertSize = log.Live100Data.AlertSize -AlertStatus = log.Live100Data.AlertStatus +AlertSize = log.ControlsState.AlertSize +AlertStatus = log.ControlsState.AlertStatus class AlertManager(object): diff --git a/selfdrive/controls/lib/alerts.py b/selfdrive/controls/lib/alerts.py index 17caf7fbf..d6e3f4535 100644 --- a/selfdrive/controls/lib/alerts.py +++ b/selfdrive/controls/lib/alerts.py @@ -9,8 +9,8 @@ class Priority: HIGH = 4 HIGHEST = 5 -AlertSize = log.Live100Data.AlertSize -AlertStatus = log.Live100Data.AlertStatus +AlertSize = log.ControlsState.AlertSize +AlertStatus = log.ControlsState.AlertStatus AudibleAlert = car.CarControl.HUDControl.AudibleAlert VisualAlert = car.CarControl.HUDControl.VisualAlert @@ -171,6 +171,20 @@ ALERTS = [ AlertStatus.normal, AlertSize.mid, Priority.LOW_LOWEST, VisualAlert.none, AudibleAlert.none, 0., 0., 15.), + Alert( + "startupNoControl", + "Dashcam mode", + "Always keep hands on wheel and eyes on road", + AlertStatus.normal, AlertSize.mid, + Priority.LOW_LOWEST, VisualAlert.none, AudibleAlert.none, 0., 0., 15.), + + Alert( + "startupNoCar", + "Dashcam mode with unsupported car", + "Always keep hands on wheel and eyes on road", + AlertStatus.normal, AlertSize.mid, + Priority.LOW_LOWEST, VisualAlert.none, AudibleAlert.none, 0., 0., 15.), + Alert( "ethicalDilemma", "TAKE CONTROL IMMEDIATELY", @@ -277,6 +291,13 @@ ALERTS = [ AlertStatus.normal, AlertSize.mid, Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), + Alert( + "sensorDataInvalidNoEntry", + "openpilot Unavailable", + "No Data from EON Sensors", + AlertStatus.normal, AlertSize.mid, + Priority.LOW, VisualAlert.none, AudibleAlert.chimeError, .4, 2., 3.), + # Cancellation alerts causing soft disabling Alert( "overheat", @@ -625,6 +646,13 @@ ALERTS = [ AlertStatus.normal, AlertSize.mid, Priority.LOW_LOWEST, VisualAlert.none, AudibleAlert.none, 0., 0., .2), + Alert( + "sensorDataInvalidPermanent", + "No Data from EON Sensors", + "Reboot your EON", + AlertStatus.normal, AlertSize.mid, + Priority.LOW_LOWEST, VisualAlert.none, AudibleAlert.none, 0., 0., .2), + Alert( "vehicleModelInvalid", "Vehicle Parameter Identification Failed", diff --git a/selfdrive/controls/lib/cluster/LICENSE b/selfdrive/controls/lib/cluster/LICENSE new file mode 100644 index 000000000..ab8b4db7d --- /dev/null +++ b/selfdrive/controls/lib/cluster/LICENSE @@ -0,0 +1,13 @@ +Copyright: + * fastcluster_dm.cpp & fastcluster_R_dm.cpp: + © 2011 Daniel Müllner + * fastcluster.(h|cpp) & demo.cpp & plotresult.r: + © 2018 Christoph Dalitz +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/selfdrive/controls/lib/cluster/Makefile b/selfdrive/controls/lib/cluster/Makefile new file mode 100644 index 000000000..ed5edfb59 --- /dev/null +++ b/selfdrive/controls/lib/cluster/Makefile @@ -0,0 +1,28 @@ +CC = clang +CXX = clang++ + +CPPFLAGS = -Wall -g -fPIC -std=c++11 -O2 + +OBJS = fastcluster.o test.o +DEPS := $(OBJS:.o=.d) + +all: libfastcluster.so + +test: libfastcluster.so test.o + $(CXX) -g -L. -lfastcluster -o $@ $+ + +valgrind: test + valgrind --leak-check=full ./test + + +libfastcluster.so: fastcluster.o + $(CXX) -g -shared -o $@ $+ + +%.o: %.cpp + $(CXX) $(CPPFLAGS) -MMD -c $*.cpp + +clean: + rm -f $(OBJS) $(DEPS) libfastcluster.so test + + +-include $(DEPS) diff --git a/selfdrive/controls/lib/cluster/README b/selfdrive/controls/lib/cluster/README new file mode 100644 index 000000000..acb18bc72 --- /dev/null +++ b/selfdrive/controls/lib/cluster/README @@ -0,0 +1,79 @@ +C++ interface to fast hierarchical clustering algorithms +======================================================== + +This is a simplified C++ interface to fast implementations of hierarchical +clustering by Daniel Müllner. The original library with interfaces to R +and Python is described in: + +Daniel Müllner: "fastcluster: Fast Hierarchical, Agglomerative Clustering +Routines for R and Python." Journal of Statistical Software 53 (2013), +no. 9, pp. 1–18, http://www.jstatsoft.org/v53/i09/ + + +Usage of the library +-------------------- + +For using the library, the following source files are needed: + +fastcluster_dm.cpp, fastcluster_R_dm.cpp + original code by Daniel Müllner + these are included by fastcluster.cpp via #include, and therefore + need not be compiled to object code + +fastcluster.[h|cpp] + simplified C++ interface + fastcluster.cpp is the only file that must be compiled + +The library provides the clustering function *hclust_fast* for +creating the dendrogram information in an encoding as used by the +R function *hclust*. For a description of the parameters, see fastcluster.h. +Its parameter *method* can be one of + +HCLUST_METHOD_SINGLE + single link with the minimum spanning tree algorithm (Rohlf, 1973) + +HHCLUST_METHOD_COMPLETE + complete link with the nearest-neighbor-chain algorithm (Murtagh, 1984) + +HCLUST_METHOD_AVERAGE + complete link with the nearest-neighbor-chain algorithm (Murtagh, 1984) + +HCLUST_METHOD_MEDIAN + median link with the generic algorithm (Müllner, 2011) + +For splitting the dendrogram into clusters, the two functions *cutree_k* +and *cutree_cdist* are provided. + +Note that output parameters must be allocated beforehand, e.g. + int* merge = new int[2*(npoints-1)]; +For a complete usage example, see lines 135-142 of demo.cpp. + + +Demonstration program +--------------------- + +A simple demo is implemented in demo.cpp, which can be compiled and run with + + make + ./hclust-demo -m complete lines.csv + +It creates two clusters of line segments such that the segment angle between +line segments of different clusters have a maximum (cosine) dissimilarity. +For visualizing the result, plotresult.r can be used as follows +(requires R to be installed): + + ./hclust-demo -m complete lines.csv | Rscript plotresult.r + + +Authors & Copyright +------------------- + +Daniel Müllner, 2011, +Christoph Dalitz, 2018, + + +License +------- + +This code is provided under a BSD-style license. +See the file LICENSE for details. diff --git a/selfdrive/controls/lib/cluster/__init__.py b/selfdrive/controls/lib/cluster/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/selfdrive/controls/lib/cluster/fastcluster.cpp b/selfdrive/controls/lib/cluster/fastcluster.cpp new file mode 100644 index 000000000..6b0af725c --- /dev/null +++ b/selfdrive/controls/lib/cluster/fastcluster.cpp @@ -0,0 +1,218 @@ +// +// C++ standalone verion of fastcluster by Daniel Müllner +// +// Copyright: Christoph Dalitz, 2018 +// Daniel Müllner, 2011 +// License: BSD style license +// (see the file LICENSE for details) +// + + +#include +#include +#include + + +extern "C" { +#include "fastcluster.h" +} + +// Code by Daniel Müllner +// workaround to make it usable as a standalone version (without R) +bool fc_isnan(double x) { return false; } +#include "fastcluster_dm.cpp" +#include "fastcluster_R_dm.cpp" + +extern "C" { +// +// Assigns cluster labels (0, ..., nclust-1) to the n points such +// that the cluster result is split into nclust clusters. +// +// Input arguments: +// n = number of observables +// merge = clustering result in R format +// nclust = number of clusters +// Output arguments: +// labels = allocated integer array of size n for result +// + void cutree_k(int n, const int* merge, int nclust, int* labels) { + + int k,m1,m2,j,l; + + if (nclust > n || nclust < 2) { + for (j=0; j last_merge(n, 0); + for (k=1; k<=(n-nclust); k++) { + // (m1,m2) = merge[k,] + m1 = merge[k-1]; + m2 = merge[n-1+k-1]; + if (m1 < 0 && m2 < 0) { // both single observables + last_merge[-m1-1] = last_merge[-m2-1] = k; + } + else if (m1 < 0 || m2 < 0) { // one is a cluster + if(m1 < 0) { j = -m1; m1 = m2; } else j = -m2; + // merging single observable and cluster + for(l = 0; l < n; l++) + if (last_merge[l] == m1) + last_merge[l] = k; + last_merge[j-1] = k; + } + else { // both cluster + for(l=0; l < n; l++) { + if( last_merge[l] == m1 || last_merge[l] == m2 ) + last_merge[l] = k; + } + } + } + + // assign cluster labels + int label = 0; + std::vector z(n,-1); + for (j=0; j= cdist + // + // Input arguments: + // n = number of observables + // merge = clustering result in R format + // height = cluster distance at each merge step + // cdist = cutoff cluster distance + // Output arguments: + // labels = allocated integer array of size n for result + // + void cutree_cdist(int n, const int* merge, double* height, double cdist, int* labels) { + + int k; + + for (k=0; k<(n-1); k++) { + if (height[k] >= cdist) { + break; + } + } + cutree_k(n, merge, n-k, labels); + } + + + // + // Hierarchical clustering with one of Daniel Muellner's fast algorithms + // + // Input arguments: + // n = number of observables + // distmat = condensed distance matrix, i.e. an n*(n-1)/2 array representing + // the upper triangle (without diagonal elements) of the distance + // matrix, e.g. for n=4: + // d00 d01 d02 d03 + // d10 d11 d12 d13 -> d01 d02 d03 d12 d13 d23 + // d20 d21 d22 d23 + // d30 d31 d32 d33 + // method = cluster metric (see enum method_code) + // Output arguments: + // merge = allocated (n-1)x2 matrix (2*(n-1) array) for storing result. + // Result follows R hclust convention: + // - observabe indices start with one + // - merge[i][] contains the merged nodes in step i + // - merge[i][j] is negative when the node is an atom + // height = allocated (n-1) array with distances at each merge step + // Return code: + // 0 = ok + // 1 = invalid method + // + int hclust_fast(int n, double* distmat, int method, int* merge, double* height) { + + // call appropriate culstering function + cluster_result Z2(n-1); + if (method == HCLUST_METHOD_SINGLE) { + // single link + MST_linkage_core(n, distmat, Z2); + } + else if (method == HCLUST_METHOD_COMPLETE) { + // complete link + NN_chain_core(n, distmat, NULL, Z2); + } + else if (method == HCLUST_METHOD_AVERAGE) { + // best average distance + double* members = new double[n]; + for (int i=0; i(n, distmat, members, Z2); + delete[] members; + } + else if (method == HCLUST_METHOD_MEDIAN) { + // best median distance (beware: O(n^3)) + generic_linkage(n, distmat, NULL, Z2); + } + else if (method == HCLUST_METHOD_CENTROID) { + // best centroid distance (beware: O(n^3)) + double* members = new double[n]; + for (int i=0; i(n, distmat, members, Z2); + delete[] members; + } + else { + return 1; + } + + int* order = new int[n]; + if (method == HCLUST_METHOD_MEDIAN || method == HCLUST_METHOD_CENTROID) { + generate_R_dendrogram(merge, height, order, Z2, n); + } else { + generate_R_dendrogram(merge, height, order, Z2, n); + } + delete[] order; // only needed for visualization + + return 0; + } + + + // Build condensed distance matrix + // Input arguments: + // n = number of observables + // m = dimension of observable + // Output arguments: + // out = allocated integer array of size n * (n - 1) / 2 for result + void hclust_pdist(int n, int m, double* pts, double* out) { + int ii = 0; + for (int i = 0; i < n; i++){ + for (int j = i + 1; j < n; j++){ + // Compute euclidian distance + double d = 0; + for (int k = 0; k < m; k ++){ + double error = pts[i * m + k] - pts[j * m + k]; + d += (error * error); + } + out[ii] = d;//sqrt(d); + ii++; + } + } + } + + void cluster_points_centroid(int n, int m, double* pts, double dist, int* idx) { + double* pdist = new double[n * (n - 1) / 2]; + int* merge = new int[2 * (n - 1)]; + double* height = new double[n - 1]; + + hclust_pdist(n, m, pts, pdist); + hclust_fast(n, pdist, HCLUST_METHOD_CENTROID, merge, height); + cutree_cdist(n, merge, height, dist, idx); + + delete[] pdist; + delete[] merge; + delete[] height; + } +} diff --git a/selfdrive/controls/lib/cluster/fastcluster.h b/selfdrive/controls/lib/cluster/fastcluster.h new file mode 100644 index 000000000..56c63b6a5 --- /dev/null +++ b/selfdrive/controls/lib/cluster/fastcluster.h @@ -0,0 +1,77 @@ +// +// C++ standalone verion of fastcluster by Daniel Muellner +// +// Copyright: Daniel Muellner, 2011 +// Christoph Dalitz, 2018 +// License: BSD style license +// (see the file LICENSE for details) +// + +#ifndef fastclustercpp_H +#define fastclustercpp_H + +// +// Assigns cluster labels (0, ..., nclust-1) to the n points such +// that the cluster result is split into nclust clusters. +// +// Input arguments: +// n = number of observables +// merge = clustering result in R format +// nclust = number of clusters +// Output arguments: +// labels = allocated integer array of size n for result +// +void cutree_k(int n, const int* merge, int nclust, int* labels); + +// +// Assigns cluster labels (0, ..., nclust-1) to the n points such +// that the hierarchical clsutering is stopped at cluster distance cdist +// +// Input arguments: +// n = number of observables +// merge = clustering result in R format +// height = cluster distance at each merge step +// cdist = cutoff cluster distance +// Output arguments: +// labels = allocated integer array of size n for result +// +void cutree_cdist(int n, const int* merge, double* height, double cdist, int* labels); + +// +// Hierarchical clustering with one of Daniel Muellner's fast algorithms +// +// Input arguments: +// n = number of observables +// distmat = condensed distance matrix, i.e. an n*(n-1)/2 array representing +// the upper triangle (without diagonal elements) of the distance +// matrix, e.g. for n=4: +// d00 d01 d02 d03 +// d10 d11 d12 d13 -> d01 d02 d03 d12 d13 d23 +// d20 d21 d22 d23 +// d30 d31 d32 d33 +// method = cluster metric (see enum method_code) +// Output arguments: +// merge = allocated (n-1)x2 matrix (2*(n-1) array) for storing result. +// Result follows R hclust convention: +// - observabe indices start with one +// - merge[i][] contains the merged nodes in step i +// - merge[i][j] is negative when the node is an atom +// height = allocated (n-1) array with distances at each merge step +// Return code: +// 0 = ok +// 1 = invalid method +// +int hclust_fast(int n, double* distmat, int method, int* merge, double* height); +enum hclust_fast_methods { + HCLUST_METHOD_SINGLE = 0, + HCLUST_METHOD_COMPLETE = 1, + HCLUST_METHOD_AVERAGE = 2, + HCLUST_METHOD_MEDIAN = 3, + HCLUST_METHOD_CENTROID = 5, +}; + +void hclust_pdist(int n, int m, double* pts, double* out); +void cluster_points_centroid(int n, int m, double* pts, double dist, int* idx); + + +#endif diff --git a/selfdrive/controls/lib/cluster/fastcluster_R_dm.cpp b/selfdrive/controls/lib/cluster/fastcluster_R_dm.cpp new file mode 100644 index 000000000..cbe126c15 --- /dev/null +++ b/selfdrive/controls/lib/cluster/fastcluster_R_dm.cpp @@ -0,0 +1,115 @@ +// +// Excerpt from fastcluster_R.cpp +// +// Copyright: Daniel Müllner, 2011 +// + +struct pos_node { + t_index pos; + int node; +}; + +void order_nodes(const int N, const int * const merge, const t_index * const node_size, int * const order) { + /* Parameters: + N : number of data points + merge : (N-1)×2 array which specifies the node indices which are + merged in each step of the clustering procedure. + Negative entries -1...-N point to singleton nodes, while + positive entries 1...(N-1) point to nodes which are themselves + parents of other nodes. + node_size : array of node sizes - makes it easier + order : output array of size N + + Runtime: Θ(N) + */ + auto_array_ptr queue(N/2); + + int parent; + int child; + t_index pos = 0; + + queue[0].pos = 0; + queue[0].node = N-2; + t_index idx = 1; + + do { + --idx; + pos = queue[idx].pos; + parent = queue[idx].node; + + // First child + child = merge[parent]; + if (child<0) { // singleton node, write this into the 'order' array. + order[pos] = -child; + ++pos; + } + else { /* compound node: put it on top of the queue and decompose it + in a later iteration. */ + queue[idx].pos = pos; + queue[idx].node = child-1; // convert index-1 based to index-0 based + ++idx; + pos += node_size[child-1]; + } + // Second child + child = merge[parent+N-1]; + if (child<0) { + order[pos] = -child; + } + else { + queue[idx].pos = pos; + queue[idx].node = child-1; + ++idx; + } + } while (idx>0); +} + +#define size_(r_) ( ((r_ +void generate_R_dendrogram(int * const merge, double * const height, int * const order, cluster_result & Z2, const int N) { + // The array "nodes" is a union-find data structure for the cluster + // identites (only needed for unsorted cluster_result input). + union_find nodes(sorted ? 0 : N); + if (!sorted) { + std::stable_sort(Z2[0], Z2[N-1]); + } + + t_index node1, node2; + auto_array_ptr node_size(N-1); + + for (t_index i=0; inode1; + node2 = Z2[i]->node2; + } + else { + node1 = nodes.Find(Z2[i]->node1); + node2 = nodes.Find(Z2[i]->node2); + // Merge the nodes in the union-find data structure by making them + // children of a new node. + nodes.Union(node1, node2); + } + // Sort the nodes in the output array. + if (node1>node2) { + t_index tmp = node1; + node1 = node2; + node2 = tmp; + } + /* Conversion between labeling conventions. + Input: singleton nodes 0,...,N-1 + compound nodes N,...,2N-2 + Output: singleton nodes -1,...,-N + compound nodes 1,...,N + */ + merge[i] = (node1(node1)-1 + : static_cast(node1)-N+1; + merge[i+N-1] = (node2(node2)-1 + : static_cast(node2)-N+1; + height[i] = Z2[i]->dist; + node_size[i] = size_(node1) + size_(node2); + } + + order_nodes(N, merge, node_size, order); +} diff --git a/selfdrive/controls/lib/cluster/fastcluster_dm.cpp b/selfdrive/controls/lib/cluster/fastcluster_dm.cpp new file mode 100644 index 000000000..8834bc24a --- /dev/null +++ b/selfdrive/controls/lib/cluster/fastcluster_dm.cpp @@ -0,0 +1,1794 @@ +/* + fastcluster: Fast hierarchical clustering routines for R and Python + + Copyright © 2011 Daniel Müllner + + + This library implements various fast algorithms for hierarchical, + agglomerative clustering methods: + + (1) Algorithms for the "stored matrix approach": the input is the array of + pairwise dissimilarities. + + MST_linkage_core: single linkage clustering with the "minimum spanning + tree algorithm (Rohlfs) + + NN_chain_core: nearest-neighbor-chain algorithm, suitable for single, + complete, average, weighted and Ward linkage (Murtagh) + + generic_linkage: generic algorithm, suitable for all distance update + formulas (Müllner) + + (2) Algorithms for the "stored data approach": the input are points in a + vector space. + + MST_linkage_core_vector: single linkage clustering for vector data + + generic_linkage_vector: generic algorithm for vector data, suitable for + the Ward, centroid and median methods. + + generic_linkage_vector_alternative: alternative scheme for updating the + nearest neighbors. This method seems faster than "generic_linkage_vector" + for the centroid and median methods but slower for the Ward method. + + All these implementation treat infinity values correctly. They throw an + exception if a NaN distance value occurs. +*/ + +// Older versions of Microsoft Visual Studio do not have the fenv header. +#ifdef _MSC_VER +#if (_MSC_VER == 1500 || _MSC_VER == 1600) +#define NO_INCLUDE_FENV +#endif +#endif +// NaN detection via fenv might not work on systems with software +// floating-point emulation (bug report for Debian armel). +#ifdef __SOFTFP__ +#define NO_INCLUDE_FENV +#endif +#ifdef NO_INCLUDE_FENV +#pragma message("Do not use fenv header.") +#else +#pragma message("Use fenv header. If there is a warning about unknown #pragma STDC FENV_ACCESS, this can be ignored.") +#pragma STDC FENV_ACCESS on +#include +#endif + +#include // for std::pow, std::sqrt +#include // for std::ptrdiff_t +#include // for std::numeric_limits<...>::infinity() +#include // for std::fill_n +#include // for std::runtime_error +#include // for std::string + +#include // also for DBL_MAX, DBL_MIN +#ifndef DBL_MANT_DIG +#error The constant DBL_MANT_DIG could not be defined. +#endif +#define T_FLOAT_MANT_DIG DBL_MANT_DIG + +#ifndef LONG_MAX +#include +#endif +#ifndef LONG_MAX +#error The constant LONG_MAX could not be defined. +#endif +#ifndef INT_MAX +#error The constant INT_MAX could not be defined. +#endif + +#ifndef INT32_MAX +#ifdef _MSC_VER +#if _MSC_VER >= 1600 +#define __STDC_LIMIT_MACROS +#include +#else +typedef __int32 int_fast32_t; +typedef __int64 int64_t; +#endif +#else +#define __STDC_LIMIT_MACROS +#include +#endif +#endif + +#define FILL_N std::fill_n +#ifdef _MSC_VER +#if _MSC_VER < 1600 +#undef FILL_N +#define FILL_N stdext::unchecked_fill_n +#endif +#endif + +// Suppress warnings about (potentially) uninitialized variables. +#ifdef _MSC_VER + #pragma warning (disable:4700) +#endif + +#ifndef HAVE_DIAGNOSTIC +#if __GNUC__ > 4 || (__GNUC__ == 4 && (__GNUC_MINOR__ >= 6)) +#define HAVE_DIAGNOSTIC 1 +#endif +#endif + +#ifndef HAVE_VISIBILITY +#if __GNUC__ >= 4 +#define HAVE_VISIBILITY 1 +#endif +#endif + +/* Since the public interface is given by the Python respectively R interface, + * we do not want other symbols than the interface initalization routines to be + * visible in the shared object file. The "visibility" switch is a GCC concept. + * Hiding symbols keeps the relocation table small and decreases startup time. + * See http://gcc.gnu.org/wiki/Visibility + */ +#if HAVE_VISIBILITY +#pragma GCC visibility push(hidden) +#endif + +typedef int_fast32_t t_index; +#ifndef INT32_MAX +#define MAX_INDEX 0x7fffffffL +#else +#define MAX_INDEX INT32_MAX +#endif +#if (LONG_MAX < MAX_INDEX) +#error The integer format "t_index" must not have a greater range than "long int". +#endif +#if (INT_MAX > MAX_INDEX) +#error The integer format "int" must not have a greater range than "t_index". +#endif +typedef double t_float; + +/* Method codes. + + These codes must agree with the METHODS array in fastcluster.R and the + dictionary mthidx in fastcluster.py. +*/ +enum method_codes { + // non-Euclidean methods + METHOD_METR_SINGLE = 0, + METHOD_METR_COMPLETE = 1, + METHOD_METR_AVERAGE = 2, + METHOD_METR_WEIGHTED = 3, + METHOD_METR_WARD = 4, + METHOD_METR_WARD_D = METHOD_METR_WARD, + METHOD_METR_CENTROID = 5, + METHOD_METR_MEDIAN = 6, + METHOD_METR_WARD_D2 = 7, + + MIN_METHOD_CODE = 0, + MAX_METHOD_CODE = 7 +}; + +enum method_codes_vector { + // Euclidean methods + METHOD_VECTOR_SINGLE = 0, + METHOD_VECTOR_WARD = 1, + METHOD_VECTOR_CENTROID = 2, + METHOD_VECTOR_MEDIAN = 3, + + MIN_METHOD_VECTOR_CODE = 0, + MAX_METHOD_VECTOR_CODE = 3 +}; + +// self-destructing array pointer +template +class auto_array_ptr{ +private: + type * ptr; + auto_array_ptr(auto_array_ptr const &); // non construction-copyable + auto_array_ptr& operator=(auto_array_ptr const &); // non copyable +public: + auto_array_ptr() + : ptr(NULL) + { } + template + auto_array_ptr(index const size) + : ptr(new type[size]) + { } + template + auto_array_ptr(index const size, value const val) + : ptr(new type[size]) + { + FILL_N(ptr, size, val); + } + ~auto_array_ptr() { + delete [] ptr; } + void free() { + delete [] ptr; + ptr = NULL; + } + template + void init(index const size) { + ptr = new type [size]; + } + template + void init(index const size, value const val) { + init(size); + FILL_N(ptr, size, val); + } + inline operator type *() const { return ptr; } +}; + +struct node { + t_index node1, node2; + t_float dist; +}; + +inline bool operator< (const node a, const node b) { + return (a.dist < b.dist); +} + +class cluster_result { +private: + auto_array_ptr Z; + t_index pos; + +public: + cluster_result(const t_index size) + : Z(size) + , pos(0) + {} + + void append(const t_index node1, const t_index node2, const t_float dist) { + Z[pos].node1 = node1; + Z[pos].node2 = node2; + Z[pos].dist = dist; + ++pos; + } + + node * operator[] (const t_index idx) const { return Z + idx; } + + /* Define several methods to postprocess the distances. All these functions + are monotone, so they do not change the sorted order of distances. */ + + void sqrt() const { + for (node * ZZ=Z; ZZ!=Z+pos; ++ZZ) { + ZZ->dist = std::sqrt(ZZ->dist); + } + } + + void sqrt(const t_float) const { // ignore the argument + sqrt(); + } + + void sqrtdouble(const t_float) const { // ignore the argument + for (node * ZZ=Z; ZZ!=Z+pos; ++ZZ) { + ZZ->dist = std::sqrt(2*ZZ->dist); + } + } + + #ifdef R_pow + #define my_pow R_pow + #else + #define my_pow std::pow + #endif + + void power(const t_float p) const { + t_float const q = 1/p; + for (node * ZZ=Z; ZZ!=Z+pos; ++ZZ) { + ZZ->dist = my_pow(ZZ->dist,q); + } + } + + void plusone(const t_float) const { // ignore the argument + for (node * ZZ=Z; ZZ!=Z+pos; ++ZZ) { + ZZ->dist += 1; + } + } + + void divide(const t_float denom) const { + for (node * ZZ=Z; ZZ!=Z+pos; ++ZZ) { + ZZ->dist /= denom; + } + } +}; + +class doubly_linked_list { + /* + Class for a doubly linked list. Initially, the list is the integer range + [0, size]. We provide a forward iterator and a method to delete an index + from the list. + + Typical use: for (i=L.start; L succ; + +private: + auto_array_ptr pred; + // Not necessarily private, we just do not need it in this instance. + +public: + doubly_linked_list(const t_index size) + // Initialize to the given size. + : start(0) + , succ(size+1) + , pred(size+1) + { + for (t_index i=0; i(2*N-3-(r_))*(r_)>>1)+(c_)-1] ) +// Z is an ((N-1)x4)-array +#define Z_(_r, _c) (Z[(_r)*4 + (_c)]) + +/* + Lookup function for a union-find data structure. + + The function finds the root of idx by going iteratively through all + parent elements until a root is found. An element i is a root if + nodes[i] is zero. To make subsequent searches faster, the entry for + idx and all its parents is updated with the root element. + */ +class union_find { +private: + auto_array_ptr parent; + t_index nextparent; + +public: + union_find(const t_index size) + : parent(size>0 ? 2*size-1 : 0, 0) + , nextparent(size) + { } + + t_index Find (t_index idx) const { + if (parent[idx] != 0 ) { // a → b + t_index p = idx; + idx = parent[idx]; + if (parent[idx] != 0 ) { // a → b → c + do { + idx = parent[idx]; + } while (parent[idx] != 0); + do { + t_index tmp = parent[p]; + parent[p] = idx; + p = tmp; + } while (parent[p] != idx); + } + } + return idx; + } + + void Union (const t_index node1, const t_index node2) { + parent[node1] = parent[node2] = nextparent++; + } +}; + +class nan_error{}; +#ifdef FE_INVALID +class fenv_error{}; +#endif + +static void MST_linkage_core(const t_index N, const t_float * const D, + cluster_result & Z2) { +/* + N: integer, number of data points + D: condensed distance matrix N*(N-1)/2 + Z2: output data structure + + The basis of this algorithm is an algorithm by Rohlf: + + F. James Rohlf, Hierarchical clustering using the minimum spanning tree, + The Computer Journal, vol. 16, 1973, p. 93–95. +*/ + t_index i; + t_index idx2; + doubly_linked_list active_nodes(N); + auto_array_ptr d(N); + + t_index prev_node; + t_float min; + + // first iteration + idx2 = 1; + min = std::numeric_limits::infinity(); + for (i=1; i tmp) + d[i] = tmp; + else if (fc_isnan(tmp)) + throw (nan_error()); +#if HAVE_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + if (d[i] < min) { + min = d[i]; + idx2 = i; + } + } + Z2.append(prev_node, idx2, min); + } +} + +/* Functions for the update of the dissimilarity array */ + +inline static void f_single( t_float * const b, const t_float a ) { + if (*b > a) *b = a; +} +inline static void f_complete( t_float * const b, const t_float a ) { + if (*b < a) *b = a; +} +inline static void f_average( t_float * const b, const t_float a, const t_float s, const t_float t) { + *b = s*a + t*(*b); + #ifndef FE_INVALID +#if HAVE_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" +#endif + if (fc_isnan(*b)) { + throw(nan_error()); + } +#if HAVE_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + #endif +} +inline static void f_weighted( t_float * const b, const t_float a) { + *b = (a+*b)*.5; + #ifndef FE_INVALID +#if HAVE_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" +#endif + if (fc_isnan(*b)) { + throw(nan_error()); + } +#if HAVE_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + #endif +} +inline static void f_ward( t_float * const b, const t_float a, const t_float c, const t_float s, const t_float t, const t_float v) { + *b = ( (v+s)*a - v*c + (v+t)*(*b) ) / (s+t+v); + //*b = a+(*b)-(t*a+s*(*b)+v*c)/(s+t+v); + #ifndef FE_INVALID +#if HAVE_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" +#endif + if (fc_isnan(*b)) { + throw(nan_error()); + } +#if HAVE_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + #endif +} +inline static void f_centroid( t_float * const b, const t_float a, const t_float stc, const t_float s, const t_float t) { + *b = s*a - stc + t*(*b); + #ifndef FE_INVALID + if (fc_isnan(*b)) { + throw(nan_error()); + } +#if HAVE_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + #endif +} +inline static void f_median( t_float * const b, const t_float a, const t_float c_4) { + *b = (a+(*b))*.5 - c_4; + #ifndef FE_INVALID +#if HAVE_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" +#endif + if (fc_isnan(*b)) { + throw(nan_error()); + } +#if HAVE_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + #endif +} + +template +static void NN_chain_core(const t_index N, t_float * const D, t_members * const members, cluster_result & Z2) { +/* + N: integer + D: condensed distance matrix N*(N-1)/2 + Z2: output data structure + + This is the NN-chain algorithm, described on page 86 in the following book: + + Fionn Murtagh, Multidimensional Clustering Algorithms, + Vienna, Würzburg: Physica-Verlag, 1985. +*/ + t_index i; + + auto_array_ptr NN_chain(N); + t_index NN_chain_tip = 0; + + t_index idx1, idx2; + + t_float size1, size2; + doubly_linked_list active_nodes(N); + + t_float min; + + for (t_float const * DD=D; DD!=D+(static_cast(N)*(N-1)>>1); + ++DD) { +#if HAVE_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wfloat-equal" +#endif + if (fc_isnan(*DD)) { + throw(nan_error()); + } +#if HAVE_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + } + + #ifdef FE_INVALID + if (feclearexcept(FE_INVALID)) throw fenv_error(); + #endif + + for (t_index j=0; jidx2) { + t_index tmp = idx1; + idx1 = idx2; + idx2 = tmp; + } + + if (method==METHOD_METR_AVERAGE || + method==METHOD_METR_WARD) { + size1 = static_cast(members[idx1]); + size2 = static_cast(members[idx2]); + members[idx2] += members[idx1]; + } + + // Remove the smaller index from the valid indices (active_nodes). + active_nodes.remove(idx1); + + switch (method) { + case METHOD_METR_SINGLE: + /* + Single linkage. + + Characteristic: new distances are never longer than the old distances. + */ + // Update the distance matrix in the range [start, idx1). + for (i=active_nodes.start; i(members[i]); + for (i=active_nodes.start; i(members[i]) ); + // Update the distance matrix in the range (idx1, idx2). + for (; i(members[i]) ); + // Update the distance matrix in the range (idx2, N). + for (i=active_nodes.succ[idx2]; i(members[i]) ); + break; + + default: + throw std::runtime_error(std::string("Invalid method.")); + } + } + #ifdef FE_INVALID + if (fetestexcept(FE_INVALID)) throw fenv_error(); + #endif +} + +class binary_min_heap { + /* + Class for a binary min-heap. The data resides in an array A. The elements of + A are not changed but two lists I and R of indices are generated which point + to elements of A and backwards. + + The heap tree structure is + + H[2*i+1] H[2*i+2] + \ / + \ / + ≤ ≤ + \ / + \ / + H[i] + + where the children must be less or equal than their parent. Thus, H[0] + contains the minimum. The lists I and R are made such that H[i] = A[I[i]] + and R[I[i]] = i. + + This implementation is not designed to handle NaN values. + */ +private: + t_float * const A; + t_index size; + auto_array_ptr I; + auto_array_ptr R; + + // no default constructor + binary_min_heap(); + // noncopyable + binary_min_heap(binary_min_heap const &); + binary_min_heap & operator=(binary_min_heap const &); + +public: + binary_min_heap(t_float * const A_, const t_index size_) + : A(A_), size(size_), I(size), R(size) + { // Allocate memory and initialize the lists I and R to the identity. This + // does not make it a heap. Call heapify afterwards! + for (t_index i=0; i>1); idx>0; ) { + --idx; + update_geq_(idx); + } + } + + inline t_index argmin() const { + // Return the minimal element. + return I[0]; + } + + void heap_pop() { + // Remove the minimal element from the heap. + --size; + I[0] = I[size]; + R[I[0]] = 0; + update_geq_(0); + } + + void remove(t_index idx) { + // Remove an element from the heap. + --size; + R[I[size]] = R[idx]; + I[R[idx]] = I[size]; + if ( H(size)<=A[idx] ) { + update_leq_(R[idx]); + } + else { + update_geq_(R[idx]); + } + } + + void replace ( const t_index idxold, const t_index idxnew, + const t_float val) { + R[idxnew] = R[idxold]; + I[R[idxnew]] = idxnew; + if (val<=A[idxold]) + update_leq(idxnew, val); + else + update_geq(idxnew, val); + } + + void update ( const t_index idx, const t_float val ) const { + // Update the element A[i] with val and re-arrange the indices to preserve + // the heap condition. + if (val<=A[idx]) + update_leq(idx, val); + else + update_geq(idx, val); + } + + void update_leq ( const t_index idx, const t_float val ) const { + // Use this when the new value is not more than the old value. + A[idx] = val; + update_leq_(R[idx]); + } + + void update_geq ( const t_index idx, const t_float val ) const { + // Use this when the new value is not less than the old value. + A[idx] = val; + update_geq_(R[idx]); + } + +private: + void update_leq_ (t_index i) const { + t_index j; + for ( ; (i>0) && ( H(i)>1) ); i=j) + heap_swap(i,j); + } + + void update_geq_ (t_index i) const { + t_index j; + for ( ; (j=2*i+1)=H(i) ) { + ++j; + if ( j>=size || H(j)>=H(i) ) break; + } + else if ( j+1 +static void generic_linkage(const t_index N, t_float * const D, t_members * const members, cluster_result & Z2) { + /* + N: integer, number of data points + D: condensed distance matrix N*(N-1)/2 + Z2: output data structure + */ + + const t_index N_1 = N-1; + t_index i, j; // loop variables + t_index idx1, idx2; // row and column indices + + auto_array_ptr n_nghbr(N_1); // array of nearest neighbors + auto_array_ptr mindist(N_1); // distances to the nearest neighbors + auto_array_ptr row_repr(N); // row_repr[i]: node number that the + // i-th row represents + doubly_linked_list active_nodes(N); + binary_min_heap nn_distances(&*mindist, N_1); // minimum heap structure for + // the distance to the nearest neighbor of each point + t_index node1, node2; // node numbers in the output + t_float size1, size2; // and their cardinalities + + t_float min; // minimum and row index for nearest-neighbor search + t_index idx; + + for (i=0; ii} D(i,j) for i in range(N-1) + t_float const * DD = D; + for (i=0; i::infinity(); + for (idx=j=i+1; ji} D(i,j) + + Normally, we have equality. However, this minimum may become invalid due + to the updates in the distance matrix. The rules are: + + 1) If mindist[i] is equal to D(i, n_nghbr[i]), this is the correct + minimum and n_nghbr[i] is a nearest neighbor. + + 2) If mindist[i] is smaller than D(i, n_nghbr[i]), this might not be the + correct minimum. The minimum needs to be recomputed. + + 3) mindist[i] is never bigger than the true minimum. Hence, we never + miss the true minimum if we take the smallest mindist entry, + re-compute the value if necessary (thus maybe increasing it) and + looking for the now smallest mindist entry until a valid minimal + entry is found. This step is done in the lines below. + + The update process for D below takes care that these rules are + fulfilled. This makes sure that the minima in the rows D(i,i+1:)of D are + re-calculated when necessary but re-calculation is avoided whenever + possible. + + The re-calculation of the minima makes the worst-case runtime of this + algorithm cubic in N. We avoid this whenever possible, and in most cases + the runtime appears to be quadratic. + */ + idx1 = nn_distances.argmin(); + if (method != METHOD_METR_SINGLE) { + while ( mindist[idx1] < D_(idx1, n_nghbr[idx1]) ) { + // Recompute the minimum mindist[idx1] and n_nghbr[idx1]. + n_nghbr[idx1] = j = active_nodes.succ[idx1]; // exists, maximally N-1 + min = D_(idx1,j); + for (j=active_nodes.succ[j]; j(members[idx1]); + size2 = static_cast(members[idx2]); + members[idx2] += members[idx1]; + } + Z2.append(node1, node2, mindist[idx1]); + + // Remove idx1 from the list of active indices (active_nodes). + active_nodes.remove(idx1); + // Index idx2 now represents the new (merged) node with label N+i. + row_repr[idx2] = N+i; + + // Update the distance matrix + switch (method) { + case METHOD_METR_SINGLE: + /* + Single linkage. + + Characteristic: new distances are never longer than the old distances. + */ + // Update the distance matrix in the range [start, idx1). + for (j=active_nodes.start; j(members[j]) ); + if (n_nghbr[j] == idx1) + n_nghbr[j] = idx2; + } + // Update the distance matrix in the range (idx1, idx2). + for (; j(members[j]) ); + if (D_(j, idx2) < mindist[j]) { + nn_distances.update_leq(j, D_(j, idx2)); + n_nghbr[j] = idx2; + } + } + // Update the distance matrix in the range (idx2, N). + if (idx2(members[j]) ); + min = D_(idx2,j); + for (j=active_nodes.succ[j]; j(members[j]) ); + if (D_(idx2,j) < min) { + min = D_(idx2,j); + n_nghbr[idx2] = j; + } + } + nn_distances.update(idx2, min); + } + break; + + case METHOD_METR_CENTROID: { + /* + Centroid linkage. + + Shorter and longer distances can occur, not bigger than max(d1,d2) + but maybe smaller than min(d1,d2). + */ + // Update the distance matrix in the range [start, idx1). + t_float s = size1/(size1+size2); + t_float t = size2/(size1+size2); + t_float stc = s*t*mindist[idx1]; + for (j=active_nodes.start; j +static void MST_linkage_core_vector(const t_index N, + t_dissimilarity & dist, + cluster_result & Z2) { +/* + N: integer, number of data points + dist: function pointer to the metric + Z2: output data structure + + The basis of this algorithm is an algorithm by Rohlf: + + F. James Rohlf, Hierarchical clustering using the minimum spanning tree, + The Computer Journal, vol. 16, 1973, p. 93–95. +*/ + t_index i; + t_index idx2; + doubly_linked_list active_nodes(N); + auto_array_ptr d(N); + + t_index prev_node; + t_float min; + + // first iteration + idx2 = 1; + min = std::numeric_limits::infinity(); + for (i=1; i tmp) + d[i] = tmp; + else if (fc_isnan(tmp)) + throw (nan_error()); +#if HAVE_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + if (d[i] < min) { + min = d[i]; + idx2 = i; + } + } + Z2.append(prev_node, idx2, min); + } +} + +template +static void generic_linkage_vector(const t_index N, + t_dissimilarity & dist, + cluster_result & Z2) { + /* + N: integer, number of data points + dist: function pointer to the metric + Z2: output data structure + + This algorithm is valid for the distance update methods + "Ward", "centroid" and "median" only! + */ + const t_index N_1 = N-1; + t_index i, j; // loop variables + t_index idx1, idx2; // row and column indices + + auto_array_ptr n_nghbr(N_1); // array of nearest neighbors + auto_array_ptr mindist(N_1); // distances to the nearest neighbors + auto_array_ptr row_repr(N); // row_repr[i]: node number that the + // i-th row represents + doubly_linked_list active_nodes(N); + binary_min_heap nn_distances(&*mindist, N_1); // minimum heap structure for + // the distance to the nearest neighbor of each point + t_index node1, node2; // node numbers in the output + t_float min; // minimum and row index for nearest-neighbor search + + for (i=0; ii} D(i,j) for i in range(N-1) + for (i=0; i::infinity(); + t_index idx; + for (idx=j=i+1; j(i,j); + } + if (tmp(idx1,j); + for (j=active_nodes.succ[j]; j(idx1,j); + if (tmp(j, idx2); + if (tmp < mindist[j]) { + nn_distances.update_leq(j, tmp); + n_nghbr[j] = idx2; + } + else if (n_nghbr[j] == idx2) + n_nghbr[j] = idx1; // invalidate + } + // Find the nearest neighbor for idx2. + if (idx2(idx2,j); + for (j=active_nodes.succ[j]; j(idx2, j); + if (tmp < min) { + min = tmp; + n_nghbr[idx2] = j; + } + } + nn_distances.update(idx2, min); + } + } + } +} + +template +static void generic_linkage_vector_alternative(const t_index N, + t_dissimilarity & dist, + cluster_result & Z2) { + /* + N: integer, number of data points + dist: function pointer to the metric + Z2: output data structure + + This algorithm is valid for the distance update methods + "Ward", "centroid" and "median" only! + */ + const t_index N_1 = N-1; + t_index i, j=0; // loop variables + t_index idx1, idx2; // row and column indices + + auto_array_ptr n_nghbr(2*N-2); // array of nearest neighbors + auto_array_ptr mindist(2*N-2); // distances to the nearest neighbors + + doubly_linked_list active_nodes(N+N_1); + binary_min_heap nn_distances(&*mindist, N_1, 2*N-2, 1); // minimum heap + // structure for the distance to the nearest neighbor of each point + + t_float min; // minimum for nearest-neighbor searches + + // Initialize the minimal distances: + // Find the nearest neighbor of each point. + // n_nghbr[i] = argmin_{j>i} D(i,j) for i in range(N-1) + for (i=1; i::infinity(); + t_index idx; + for (idx=j=0; j(i,j); + } + if (tmp + +extern "C" { +#include "fastcluster.h" +} + + +int main(int argc, const char* argv[]){ + const int n = 11; + const int m = 3; + double* pts = new double[n*m]{59.26000137, -9.35999966, -5.42500019, + 91.61999817, -0.31999999, -2.75, + 31.38000031, 0.40000001, -0.2, + 89.57999725, -8.07999992, -18.04999924, + 53.42000122, 0.63999999, -0.175, + 31.38000031, 0.47999999, -0.2, + 36.33999939, 0.16, -0.2, + 53.33999939, 0.95999998, -0.175, + 59.26000137, -9.76000023, -5.44999981, + 33.93999977, 0.40000001, -0.22499999, + 106.74000092, -5.76000023, -18.04999924}; + + int * idx = new int[n]; + int * correct_idx = new int[n]{0, 1, 2, 3, 4, 2, 5, 4, 0, 5, 6}; + + cluster_points_centroid(n, m, pts, 2.5 * 2.5, idx); + + for (int i = 0; i < n; i++){ + assert(idx[i] == correct_idx[i]); + } + + delete[] idx; + delete[] correct_idx; + delete[] pts; +} diff --git a/selfdrive/controls/lib/latcontrol_indi.py b/selfdrive/controls/lib/latcontrol_indi.py index 2e95489bc..28e37b9e2 100644 --- a/selfdrive/controls/lib/latcontrol_indi.py +++ b/selfdrive/controls/lib/latcontrol_indi.py @@ -51,7 +51,7 @@ class LatControlINDI(object): y = np.matrix([[math.radians(angle_steers)], [math.radians(angle_steers_rate)]]) self.x = np.dot(self.A_K, self.x) + np.dot(self.K, y) - indi_log = log.Live100Data.LateralINDIState.new_message() + indi_log = log.ControlsState.LateralINDIState.new_message() indi_log.steerAngle = math.degrees(self.x[0]) indi_log.steerRate = math.degrees(self.x[1]) indi_log.steerAccel = math.degrees(self.x[2]) diff --git a/selfdrive/controls/lib/latcontrol_pid.py b/selfdrive/controls/lib/latcontrol_pid.py index 600990aaa..446806239 100644 --- a/selfdrive/controls/lib/latcontrol_pid.py +++ b/selfdrive/controls/lib/latcontrol_pid.py @@ -15,7 +15,7 @@ class LatControlPID(object): self.pid.reset() def update(self, active, v_ego, angle_steers, angle_steers_rate, steer_override, CP, VM, path_plan): - pid_log = log.Live100Data.LateralPIDState.new_message() + pid_log = log.ControlsState.LateralPIDState.new_message() pid_log.steerAngle = float(angle_steers) pid_log.steerRate = float(angle_steers_rate) diff --git a/selfdrive/controls/lib/longcontrol.py b/selfdrive/controls/lib/longcontrol.py index 0b1eefea7..84c17ef37 100644 --- a/selfdrive/controls/lib/longcontrol.py +++ b/selfdrive/controls/lib/longcontrol.py @@ -2,7 +2,7 @@ from cereal import log from common.numpy_fast import clip, interp from selfdrive.controls.lib.pid import PIController -LongCtrlState = log.Live100Data.LongControlState +LongCtrlState = log.ControlsState.LongControlState STOPPING_EGO_SPEED = 0.5 MIN_CAN_SPEED = 0.3 # TODO: parametrize this in car interface diff --git a/selfdrive/controls/lib/pathplanner.py b/selfdrive/controls/lib/pathplanner.py index 5a0330ff2..f3cdffdfd 100644 --- a/selfdrive/controls/lib/pathplanner.py +++ b/selfdrive/controls/lib/pathplanner.py @@ -20,10 +20,10 @@ def calc_states_after_delay(states, v_ego, steer_angle, curvature_factor, steer_ class PathPlanner(object): def __init__(self, CP): self.MP = ModelParser() - + self.l_poly = [0., 0., 0., 0.] self.r_poly = [0., 0., 0., 0.] - + self.last_cloudlog_t = 0 context = zmq.Context() @@ -49,13 +49,13 @@ class PathPlanner(object): self.angle_steers_des_prev = 0.0 self.angle_steers_des_time = 0.0 - def update(self, rcv_times, CP, VM, CS, md, live100, live_parameters): + def update(self, rcv_times, CP, VM, CS, md, controls_state, live_parameters): v_ego = CS.carState.vEgo angle_steers = CS.carState.steeringAngle - active = live100.live100.active + active = controls_state.controlsState.active angle_offset_average = live_parameters.liveParameters.angleOffsetAverage - angle_offset_bias = live100.live100.angleModelBias + angle_offset_average + angle_offset_bias = controls_state.controlsState.angleModelBias + angle_offset_average self.MP.update(v_ego, md) @@ -123,6 +123,7 @@ class PathPlanner(object): plan_send.pathPlan.angleOffset = float(angle_offset_average) plan_send.pathPlan.valid = bool(plan_valid) plan_send.pathPlan.paramsValid = bool(live_parameters.liveParameters.valid) + plan_send.pathPlan.sensorValid = bool(live_parameters.liveParameters.sensorValid) plan_send.pathPlan.modelValid = bool(not model_dead) self.plan.send(plan_send.to_bytes()) diff --git a/selfdrive/controls/lib/planner.py b/selfdrive/controls/lib/planner.py index f4b2bf88c..c8c3d1805 100755 --- a/selfdrive/controls/lib/planner.py +++ b/selfdrive/controls/lib/planner.py @@ -114,18 +114,18 @@ class Planner(object): self.v_acc_future = min([self.mpc1.v_mpc_future, self.mpc2.v_mpc_future, v_cruise_setpoint]) - def update(self, rcv_times, CS, CP, VM, PP, live20, live100, md, live_map_data): - """Gets called when new live20 is available""" + def update(self, rcv_times, CS, CP, VM, PP, radar_state, controls_state, md, live_map_data): + """Gets called when new radarState is available""" cur_time = sec_since_boot() v_ego = CS.carState.vEgo - long_control_state = live100.live100.longControlState - v_cruise_kph = live100.live100.vCruise - force_slow_decel = live100.live100.forceDecel + long_control_state = controls_state.controlsState.longControlState + v_cruise_kph = controls_state.controlsState.vCruise + force_slow_decel = controls_state.controlsState.forceDecel v_cruise_setpoint = v_cruise_kph * CV.KPH_TO_MS - lead_1 = live20.live20.leadOne - lead_2 = live20.live20.leadTwo + lead_1 = radar_state.radarState.leadOne + lead_2 = radar_state.radarState.leadTwo enabled = (long_control_state == LongCtrlState.pid) or (long_control_state == LongCtrlState.stopping) following = lead_1.status and lead_1.dRel < 45.0 and lead_1.vLeadK > v_ego and lead_1.aLeadK > 0.0 @@ -209,18 +209,18 @@ class Planner(object): if fcw: cloudlog.info("FCW triggered %s", self.fcw_checker.counters) - radar_dead = cur_time - rcv_times['live20'] > 0.5 + radar_dead = cur_time - rcv_times['radarState'] > 0.5 - radar_errors = list(live20.live20.radarErrors) - radar_fault = car.RadarState.Error.fault in radar_errors - radar_comm_issue = car.RadarState.Error.commIssue in radar_errors + radar_errors = list(radar_state.radarState.radarErrors) + radar_fault = car.RadarData.Error.fault in radar_errors + radar_comm_issue = car.RadarData.Error.commIssue in radar_errors # **** send the plan **** plan_send = messaging.new_message() plan_send.init('plan') plan_send.plan.mdMonoTime = md.logMonoTime - plan_send.plan.l20MonoTime = live20.logMonoTime + plan_send.plan.radarStateMonoTime = radar_state.logMonoTime # longitudal plan plan_send.plan.vCruise = self.v_cruise @@ -241,7 +241,7 @@ class Planner(object): plan_send.plan.radarValid = bool(radar_valid) plan_send.plan.radarCommIssue = bool(radar_comm_issue) - plan_send.plan.processingDelay = (plan_send.logMonoTime / 1e9) - rcv_times['live20'] + plan_send.plan.processingDelay = (plan_send.logMonoTime / 1e9) - rcv_times['radarState'] # Send out fcw fcw = fcw and (self.fcw_enabled or long_control_state != LongCtrlState.off) diff --git a/selfdrive/controls/lib/radar_helpers.py b/selfdrive/controls/lib/radar_helpers.py index 99f34dfd5..7efb9f334 100644 --- a/selfdrive/controls/lib/radar_helpers.py +++ b/selfdrive/controls/lib/radar_helpers.py @@ -1,6 +1,3 @@ -import os -import sys -import platform import numpy as np from common.numpy_fast import clip, interp @@ -121,27 +118,6 @@ class Track(object): return [self.dRel, self.yRel*2, self.vRel] -# ******************* Cluster ******************* -if platform.machine() == 'aarch64': - for x in sys.path: - pp = os.path.join(x, "phonelibs/hierarchy/lib") - if os.path.isfile(os.path.join(pp, "_hierarchy.so")): - sys.path.append(pp) - break - import _hierarchy #pylint: disable=import-error -else: - from scipy.cluster import _hierarchy - - -def fcluster(Z, t, criterion='inconsistent', depth=2, R=None, monocrit=None): - # supersimplified function to get fast clustering. Got it from scipy - Z = np.asarray(Z, order='c') - n = Z.shape[0] + 1 - T = np.zeros((n,), dtype='i') - _hierarchy.cluster_dist(Z, T, float(t), int(n)) - return T - - def mean(l): return sum(l) / len(l) @@ -215,7 +191,7 @@ class Cluster(object): def oncoming(self): return all([t.oncoming for t in self.tracks]) - def toLive20(self): + def toRadarState(self): return { "dRel": float(self.dRel) - RDR_TO_LDR, "yRel": float(self.yRel), diff --git a/selfdrive/controls/plannerd.py b/selfdrive/controls/plannerd.py index 5946f6192..c152d01fd 100755 --- a/selfdrive/controls/plannerd.py +++ b/selfdrive/controls/plannerd.py @@ -1,10 +1,11 @@ #!/usr/bin/env python +import gc import zmq from collections import defaultdict from cereal import car from common.params import Params -from common.realtime import sec_since_boot +from common.realtime import sec_since_boot, set_realtime_priority from selfdrive.swaglog import cloudlog from selfdrive.services import service_list from selfdrive.controls.lib.planner import Planner @@ -14,6 +15,11 @@ import selfdrive.messaging as messaging def plannerd_thread(): + gc.disable() + + # start the loop + set_realtime_priority(2) + context = zmq.Context() params = Params() @@ -31,26 +37,27 @@ def plannerd_thread(): poller = zmq.Poller() car_state_sock = messaging.sub_sock(context, service_list['carState'].port, conflate=True, poller=poller) - live100_sock = messaging.sub_sock(context, service_list['live100'].port, conflate=True, poller=poller) - live20_sock = messaging.sub_sock(context, service_list['live20'].port, conflate=True, poller=poller) + controls_state_sock = messaging.sub_sock(context, service_list['controlsState'].port, conflate=True, poller=poller) + radar_state_sock = messaging.sub_sock(context, service_list['radarState'].port, conflate=True, poller=poller) model_sock = messaging.sub_sock(context, service_list['model'].port, conflate=True, poller=poller) - live_map_data_sock = messaging.sub_sock(context, service_list['liveMapData'].port, conflate=True, poller=poller) live_parameters_sock = messaging.sub_sock(context, service_list['liveParameters'].port, conflate=True, poller=poller) + # live_map_data_sock = messaging.sub_sock(context, service_list['liveMapData'].port, conflate=True, poller=poller) car_state = messaging.new_message() car_state.init('carState') - live100 = messaging.new_message() - live100.init('live100') + controls_state = messaging.new_message() + controls_state.init('controlsState') model = messaging.new_message() model.init('model') - live20 = messaging.new_message() - live20.init('live20') + radar_state = messaging.new_message() + radar_state.init('radarState') live_map_data = messaging.new_message() live_map_data.init('liveMapData') live_parameters = messaging.new_message() live_parameters.init('liveParameters') live_parameters.liveParameters.valid = True + live_parameters.liveParameters.sensorValid = True live_parameters.liveParameters.steerRatio = CP.steerRatio live_parameters.liveParameters.stiffnessFactor = 1.0 @@ -61,20 +68,20 @@ def plannerd_thread(): msg = messaging.recv_one(socket) rcv_times[msg.which()] = sec_since_boot() - if socket is live100_sock: - live100 = msg + if socket is controls_state_sock: + controls_state = msg elif socket is car_state_sock: car_state = msg elif socket is live_parameters_sock: live_parameters = msg elif socket is model_sock: model = msg - PP.update(rcv_times, CP, VM, car_state, model, live100, live_parameters) - elif socket is live_map_data_sock: - live_map_data = msg - elif socket is live20_sock: - live20 = msg - PL.update(rcv_times, car_state, CP, VM, PP, live20, live100, model, live_map_data) + PP.update(rcv_times, CP, VM, car_state, model, controls_state, live_parameters) + elif socket is radar_state_sock: + radar_state = msg + PL.update(rcv_times, car_state, CP, VM, PP, radar_state, controls_state, model, live_map_data) + # elif socket is live_map_data_sock: + # live_map_data = msg def main(gctx=None): diff --git a/selfdrive/controls/radard.py b/selfdrive/controls/radard.py index 46d12ae8d..c4c135c1c 100755 --- a/selfdrive/controls/radard.py +++ b/selfdrive/controls/radard.py @@ -4,14 +4,15 @@ import numpy as np import numpy.matlib import importlib from collections import defaultdict, deque -from fastcluster import linkage_vector import selfdrive.messaging as messaging from selfdrive.services import service_list from selfdrive.controls.lib.latcontrol_helpers import calc_lookahead_offset from selfdrive.controls.lib.model_parser import ModelParser -from selfdrive.controls.lib.radar_helpers import Track, Cluster, fcluster, \ +from selfdrive.controls.lib.radar_helpers import Track, Cluster, \ RDR_TO_LDR, NO_FUSION_SCORE + +from selfdrive.controls.lib.cluster.fastcluster_py import cluster_points_centroid from selfdrive.controls.lib.vehicle_model import VehicleModel from selfdrive.swaglog import cloudlog from cereal import car @@ -45,8 +46,6 @@ class EKFV1D(EKF): ## fuses camera and radar data for best lead detection -# FIXME: radard has a memory leak of about 50MB/hr -# BOUNTY: $100 coupon on shop.comma.ai def radard_thread(gctx=None): set_realtime_priority(2) @@ -65,7 +64,7 @@ def radard_thread(gctx=None): # *** subscribe to features and model from visiond poller = zmq.Poller() model = messaging.sub_sock(context, service_list['model'].port, conflate=True, poller=poller) - live100 = messaging.sub_sock(context, service_list['live100'].port, conflate=True, poller=poller) + controls_state_sock = messaging.sub_sock(context, service_list['controlsState'].port, conflate=True, poller=poller) live_parameters_sock = messaging.sub_sock(context, service_list['liveParameters'].port, conflate=True, poller=poller) # Default parameters @@ -79,10 +78,10 @@ def radard_thread(gctx=None): RI = RadarInterface(CP) last_md_ts = 0 - last_l100_ts = 0 + last_controls_state_ts = 0 - # *** publish live20 and liveTracks - live20 = messaging.pub_sock(context, service_list['live20'].port) + # *** publish radarState and liveTracks + radarState = messaging.pub_sock(context, service_list['radarState'].port) liveTracks = messaging.pub_sock(context, service_list['liveTracks'].port) path_x = np.arange(0.0, 140.0, 0.1) # 140 meters is max @@ -108,7 +107,7 @@ def radard_thread(gctx=None): v_ego_hist_v = deque(maxlen=v_len) v_ego_t_aligned = 0. - rk = Ratekeeper(rate, print_delay_threshold=np.inf) + rk = Ratekeeper(rate, print_delay_threshold=None) while 1: rr = RI.update() @@ -116,29 +115,29 @@ def radard_thread(gctx=None): for pt in rr.points: ar_pts[pt.trackId] = [pt.dRel + RDR_TO_LDR, pt.yRel, pt.vRel, pt.measured] - # receive the live100s - l100 = None + # receive the controlsStates + controls_state = None md = None for socket, event in poller.poll(0): - if socket is live100: - l100 = messaging.recv_one(socket) + if socket is controls_state_sock: + controls_state = messaging.recv_one(socket) elif socket is model: md = messaging.recv_one(socket) elif socket is live_parameters_sock: live_parameters = messaging.recv_one(socket) VM.update_params(live_parameters.liveParameters.stiffnessFactor, live_parameters.liveParameters.steerRatio) - if l100 is not None: - active = l100.live100.active - v_ego = l100.live100.vEgo - steer_angle = l100.live100.angleSteers - steer_override = l100.live100.steerOverride + if controls_state is not None: + active = controls_state.controlsState.active + v_ego = controls_state.controlsState.vEgo + steer_angle = controls_state.controlsState.angleSteers + steer_override = controls_state.controlsState.steerOverride v_ego_hist_v.append(v_ego) v_ego_hist_t.append(float(rk.frame)/rate) - last_l100_ts = l100.logMonoTime + last_controls_state_ts = controls_state.logMonoTime if v_ego is None: continue @@ -231,16 +230,15 @@ def radard_thread(gctx=None): # If we have multiple points, cluster them if len(track_pts) > 1: - link = linkage_vector(track_pts, method='centroid') - cluster_idxs = fcluster(link, 2.5, criterion='distance') - clusters = [None]*max(cluster_idxs) + cluster_idxs = cluster_points_centroid(track_pts, 2.5) + clusters = [None] * (max(cluster_idxs) + 1) for idx in xrange(len(track_pts)): - cluster_i = cluster_idxs[idx]-1 - - if clusters[cluster_i] == None: + cluster_i = cluster_idxs[idx] + if clusters[cluster_i] is None: clusters[cluster_i] = Cluster() clusters[cluster_i].add(tracks[idens[idx]]) + elif len(track_pts) == 1: # TODO: why do we need this? clusters = [Cluster()] @@ -263,24 +261,24 @@ def radard_thread(gctx=None): lead2_clusters.sort(key=lambda x: x.dRel) lead2_len = len(lead2_clusters) - # *** publish live20 *** + # *** publish radarState *** dat = messaging.new_message() - dat.init('live20') - dat.live20.mdMonoTime = last_md_ts - dat.live20.canMonoTimes = list(rr.canMonoTimes) - dat.live20.radarErrors = list(rr.errors) - dat.live20.l100MonoTime = last_l100_ts + dat.init('radarState') + dat.radarState.mdMonoTime = last_md_ts + dat.radarState.canMonoTimes = list(rr.canMonoTimes) + dat.radarState.radarErrors = list(rr.errors) + dat.radarState.controlsStateMonoTime = last_controls_state_ts if lead_len > 0: - dat.live20.leadOne = lead_clusters[0].toLive20() + dat.radarState.leadOne = lead_clusters[0].toRadarState() if lead2_len > 0: - dat.live20.leadTwo = lead2_clusters[0].toLive20() + dat.radarState.leadTwo = lead2_clusters[0].toRadarState() else: - dat.live20.leadTwo.status = False + dat.radarState.leadTwo.status = False else: - dat.live20.leadOne.status = False + dat.radarState.leadOne.status = False - dat.live20.cumLagMs = -rk.remaining*1000. - live20.send(dat.to_bytes()) + dat.radarState.cumLagMs = -rk.remaining*1000. + radarState.send(dat.to_bytes()) # *** publish tracks for UI debugging (keep last) *** dat = messaging.new_message() diff --git a/selfdrive/controls/tests/test_clustering.py b/selfdrive/controls/tests/test_clustering.py new file mode 100644 index 000000000..14c0e23fe --- /dev/null +++ b/selfdrive/controls/tests/test_clustering.py @@ -0,0 +1,138 @@ +import time +import unittest +import numpy as np +from fastcluster import linkage_vector +from scipy.cluster import _hierarchy +from scipy.spatial.distance import pdist + +from selfdrive.controls.lib.cluster.fastcluster_py import hclust, ffi +from selfdrive.controls.lib.cluster.fastcluster_py import cluster_points_centroid + + +def fcluster(Z, t, criterion='inconsistent', depth=2, R=None, monocrit=None): + # supersimplified function to get fast clustering. Got it from scipy + Z = np.asarray(Z, order='c') + n = Z.shape[0] + 1 + T = np.zeros((n,), dtype='i') + _hierarchy.cluster_dist(Z, T, float(t), int(n)) + return T + + +TRACK_PTS = np.array([[59.26000137, -9.35999966, -5.42500019], + [91.61999817, -0.31999999, -2.75], + [31.38000031, 0.40000001, -0.2], + [89.57999725, -8.07999992, -18.04999924], + [53.42000122, 0.63999999, -0.175], + [31.38000031, 0.47999999, -0.2], + [36.33999939, 0.16, -0.2], + [53.33999939, 0.95999998, -0.175], + [59.26000137, -9.76000023, -5.44999981], + [33.93999977, 0.40000001, -0.22499999], + [106.74000092, -5.76000023, -18.04999924]]) + +CORRECT_LINK = np.array([[2., 5., 0.07999998, 2.], + [4., 7., 0.32984889, 2.], + [0., 8., 0.40078104, 2.], + [6., 9., 2.41209933, 2.], + [11., 14., 3.76342275, 4.], + [12., 13., 13.02297651, 4.], + [1., 3., 17.27626057, 2.], + [10., 17., 17.92918845, 3.], + [15., 16., 23.68525366, 8.], + [18., 19., 52.52351319, 11.]]) + +CORRECT_LABELS = np.array([7, 1, 4, 2, 6, 4, 5, 6, 7, 5, 3], dtype=np.int32) + + +def plot_cluster(pts, idx_old, idx_new): + import matplotlib.pyplot as plt + m = 'Set1' + + plt.figure() + plt.subplot(1, 2, 1) + plt.scatter(pts[:, 0], pts[:, 1], c=idx_old, cmap=m) + plt.title("Old") + plt.colorbar() + plt.subplot(1, 2, 2) + plt.scatter(pts[:, 0], pts[:, 1], c=idx_new, cmap=m) + plt.title("New") + plt.colorbar() + + plt.show() + + +def same_clusters(correct, other): + correct = np.asarray(correct) + other = np.asarray(other) + if len(correct) != len(other): + return False + + for i in range(len(correct)): + c = np.where(correct == correct[i]) + o = np.where(other == other[i]) + if not np.array_equal(c, o): + return False + return True + + +class TestClustering(unittest.TestCase): + def test_scipy_clustering(self): + old_link = linkage_vector(TRACK_PTS, method='centroid') + old_cluster_idxs = fcluster(old_link, 2.5, criterion='distance') + + np.testing.assert_allclose(old_link, CORRECT_LINK) + np.testing.assert_allclose(old_cluster_idxs, CORRECT_LABELS) + + def test_pdist(self): + pts = np.ascontiguousarray(TRACK_PTS, dtype=np.float64) + pts_ptr = ffi.cast("double *", pts.ctypes.data) + + n, m = pts.shape + out = np.zeros((n * (n - 1) / 2, ), dtype=np.float64) + out_ptr = ffi.cast("double *", out.ctypes.data) + hclust.hclust_pdist(n, m, pts_ptr, out_ptr) + + np.testing.assert_allclose(out, np.power(pdist(TRACK_PTS), 2)) + + def test_cpp_clustering(self): + pts = np.ascontiguousarray(TRACK_PTS, dtype=np.float64) + pts_ptr = ffi.cast("double *", pts.ctypes.data) + n, m = pts.shape + + labels = np.zeros((n, ), dtype=np.int32) + labels_ptr = ffi.cast("int *", labels.ctypes.data) + hclust.cluster_points_centroid(n, m, pts_ptr, 2.5**2, labels_ptr) + self.assertTrue(same_clusters(CORRECT_LABELS, labels)) + + def test_cpp_wrapper_clustering(self): + labels = cluster_points_centroid(TRACK_PTS, 2.5) + self.assertTrue(same_clusters(CORRECT_LABELS, labels)) + + def test_random_cluster(self): + np.random.seed(1337) + N = 1000 + + t_old = 0. + t_new = 0. + + for _ in range(N): + n = int(np.random.uniform(2, 32)) + x = np.random.uniform(-10, 50, (n, 1)) + y = np.random.uniform(-5, 5, (n, 1)) + vrel = np.random.uniform(-5, 5, (n, 1)) + pts = np.hstack([x, y, vrel]) + + t = time.time() + old_link = linkage_vector(pts, method='centroid') + old_cluster_idx = fcluster(old_link, 2.5, criterion='distance') + t_old += time.time() - t + + t = time.time() + cluster_idx = cluster_points_centroid(pts, 2.5) + t_new += time.time() - t + + self.assertTrue(same_clusters(old_cluster_idx, cluster_idx)) + + +if __name__ == "__main__": + unittest.main() diff --git a/selfdrive/controls/tests/test_following_distance.py b/selfdrive/controls/tests/test_following_distance.py index a3cb63601..228636e67 100644 --- a/selfdrive/controls/tests/test_following_distance.py +++ b/selfdrive/controls/tests/test_following_distance.py @@ -51,7 +51,7 @@ def run_following_distance_simulation(v_lead, t_end=200.0): CS.carState.aEgo = a_ego # Setup lead packet - lead = log.Live20Data.LeadData.new_message() + lead = log.RadarState.LeadData.new_message() lead.status = True lead.dRel = x_lead - x_ego lead.vLead = v_lead diff --git a/selfdrive/debug/cpu_usage_stat.py b/selfdrive/debug/cpu_usage_stat.py old mode 100644 new mode 100755 index 3ba96fd00..55723ff35 --- a/selfdrive/debug/cpu_usage_stat.py +++ b/selfdrive/debug/cpu_usage_stat.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python import psutil import time import os diff --git a/selfdrive/locationd/kalman/chi2_lookup.py b/selfdrive/locationd/kalman/chi2_lookup.py new file mode 100644 index 000000000..f45b4577f --- /dev/null +++ b/selfdrive/locationd/kalman/chi2_lookup.py @@ -0,0 +1,21 @@ +import numpy as np +import os + + +def gen_chi2_ppf_lookup(max_dim=200): + from scipy.stats import chi2 + table = np.zeros((max_dim, 98)) + for dim in range(1,max_dim): + table[dim] = chi2.ppf(np.arange(.01, .99, .01), dim) + #outfile = open('chi2_lookup_table', 'w') + np.save('chi2_lookup_table', table) + + +def chi2_ppf(p, dim): + table = np.load(os.path.dirname(os.path.realpath(__file__)) + '/chi2_lookup_table.npy') + result = np.interp(p, np.arange(.01, .99, .01), table[dim]) + return result + + +if __name__== "__main__": + gen_chi2_ppf_lookup() diff --git a/selfdrive/locationd/kalman/chi2_lookup_table.npy b/selfdrive/locationd/kalman/chi2_lookup_table.npy new file mode 100644 index 000000000..6f1bd959c Binary files /dev/null and b/selfdrive/locationd/kalman/chi2_lookup_table.npy differ diff --git a/selfdrive/locationd/kalman/ekf_sym.py b/selfdrive/locationd/kalman/ekf_sym.py index 8b537c699..a1f282ab0 100644 --- a/selfdrive/locationd/kalman/ekf_sym.py +++ b/selfdrive/locationd/kalman/ekf_sym.py @@ -5,8 +5,7 @@ import numpy as np from numpy import dot from common.ffi_wrapper import compile_code, wrap_compiled from common.sympy_helpers import sympy_into_c -import scipy -from scipy.stats import chi2 +from chi2_lookup import chi2_ppf EXTERNAL_PATH = os.path.dirname(os.path.abspath(__file__)) @@ -19,12 +18,11 @@ def solve(a, b): return np.linalg.solve(a, b) def null(H, eps=1e-12): - from scipy import linalg - u, s, vh = linalg.svd(H) + u, s, vh = np.linalg.svd(H) padding = max(0,np.shape(H)[1]-np.shape(s)[0]) null_mask = np.concatenate(((s <= eps), np.ones((padding,),dtype=bool)),axis=0) - null_space = scipy.compress(null_mask, vh, axis=0) - return scipy.transpose(null_space) + null_space = np.compress(null_mask, vh, axis=0) + return np.transpose(null_space) def gen_code(name, f_sym, dt_sym, x_sym, obs_eqs, dim_x, dim_err, eskf_params=None, msckf_params=None, maha_test_kinds=[]): # optional state transition matrix, H modifier @@ -121,7 +119,7 @@ def gen_code(name, f_sym, dt_sym, x_sym, obs_eqs, dim_x, dim_err, eskf_params=No else: He_str = 'NULL' # ea_dim = 1 # not really dim of ea but makes c function work - maha_thresh = chi2.ppf(0.95, int(h_sym.shape[0])) # mahalanobis distance for outlier detection + maha_thresh = chi2_ppf(0.95, int(h_sym.shape[0])) # mahalanobis distance for outlier detection maha_test = kind in maha_test_kinds extra_post += """ void update_%d(double *in_x, double *in_P, double *in_z, double *in_R, double *in_ea) { @@ -471,7 +469,7 @@ class EKF_sym(object): if self.msckf and kind in self.maha_test_kinds: a = np.linalg.inv(H.dot(P).dot(H.T) + R) maha_dist = y.T.dot(a.dot(y)) - if maha_dist > chi2.ppf(0.95, y.shape[0]): + if maha_dist > chi2_ppf(0.95, y.shape[0]): R = 10e16*R # *** same below this line *** @@ -513,7 +511,7 @@ class EKF_sym(object): a = np.linalg.inv(H.dot(P).dot(H.T) + R) maha_dist = y.T.dot(a.dot(y)) - if maha_dist > chi2.ppf(maha_thresh, y.shape[0]): + if maha_dist > chi2_ppf(maha_thresh, y.shape[0]): return False else: return True diff --git a/selfdrive/locationd/locationd_local.py b/selfdrive/locationd/locationd_local.py index cc5498cf3..627f87303 100755 --- a/selfdrive/locationd/locationd_local.py +++ b/selfdrive/locationd/locationd_local.py @@ -32,11 +32,13 @@ MAX_SR_TH = 1.9 LEARNING_RATE = 3 + class Localizer(object): def __init__(self, disabled_logs=None, dog=None): self.kf = LocLocalKalman() self.reset_kalman() + self.sensor_data_t = 0.0 self.max_age = .2 # seconds self.calibration_valid = False @@ -73,10 +75,10 @@ class Localizer(object): self.update_kalman(current_time, ObservationKind.CAMERA_ODO_TRANSLATION, np.concatenate([log.cameraOdometry.trans, log.cameraOdometry.transStd])) - def handle_live100(self, log, current_time): + def handle_controls_state(self, log, current_time): self.speed_counter += 1 if self.speed_counter % 5 == 0: - self.update_kalman(current_time, ObservationKind.ODOMETRIC_SPEED, np.array([log.live100.vEgo])) + self.update_kalman(current_time, ObservationKind.ODOMETRIC_SPEED, np.array([log.controlsState.vEgo])) def handle_sensors(self, log, current_time): for sensor_reading in log.sensorEvents: @@ -92,9 +94,10 @@ class Localizer(object): if typ in self.disabled_logs: return if typ == "sensorEvents": + self.sensor_data_t = current_time self.handle_sensors(log, current_time) - elif typ == "live100": - self.handle_live100(log, current_time) + elif typ == "controlsState": + self.handle_controls_state(log, current_time) elif typ == "cameraOdometry": self.handle_cam_odo(log, current_time) @@ -173,7 +176,7 @@ def locationd_thread(gctx, addr, disabled_logs): ctx = zmq.Context() poller = zmq.Poller() - live100_socket = messaging.sub_sock(ctx, service_list['live100'].port, poller, addr=addr, conflate=True) + controls_state_socket = messaging.sub_sock(ctx, service_list['controlsState'].port, poller, addr=addr, conflate=True) sensor_events_socket = messaging.sub_sock(ctx, service_list['sensorEvents'].port, poller, addr=addr, conflate=True) camera_odometry_socket = messaging.sub_sock(ctx, service_list['cameraOdometry'].port, poller, addr=addr, conflate=True) @@ -191,17 +194,19 @@ def locationd_thread(gctx, addr, disabled_logs): # Check if car model matches if params is not None: params = json.loads(params) - if params.get('carFingerprint', None) != CP.carFingerprint: + if (params.get('carFingerprint', None) != CP.carFingerprint) or (params.get('carVin', CP.carVin) != CP.carVin): cloudlog.info("Parameter learner found parameters for wrong car.") params = None if params is None: params = { 'carFingerprint': CP.carFingerprint, + 'carVin': CP.carVin, 'angleOffsetAverage': 0.0, 'stiffnessFactor': 1.0, 'steerRatio': VM.sR, } + params_reader.put("LiveParameters", json.dumps(params)) cloudlog.info("Parameter learner resetting to default values") cloudlog.info("Parameter starting with: %s" % str(params)) @@ -213,29 +218,33 @@ def locationd_thread(gctx, addr, disabled_logs): steer_ratio=params['steerRatio'], learning_rate=LEARNING_RATE) - i = 0 + i = 1 while True: for socket, event in poller.poll(timeout=1000): log = messaging.recv_one(socket) localizer.handle_log(log) - if socket is live100_socket: + if socket is controls_state_socket: if not localizer.kf.t: continue if i % LEARNING_RATE == 0: - # live100 is not updating the Kalman Filter, so update KF manually + # controlsState is not updating the Kalman Filter, so update KF manually localizer.kf.predict(1e-9 * log.logMonoTime) predicted_state = localizer.kf.x yaw_rate = -float(predicted_state[5]) - steering_angle = math.radians(log.live100.angleSteers) - params_valid = learner.update(yaw_rate, log.live100.vEgo, steering_angle) + steering_angle = math.radians(log.controlsState.angleSteers) + params_valid = learner.update(yaw_rate, log.controlsState.vEgo, steering_angle) + + log_t = 1e-9 * log.logMonoTime + sensor_data_age = log_t - localizer.sensor_data_t params = messaging.new_message() params.init('liveParameters') params.liveParameters.valid = bool(params_valid) + params.liveParameters.sensorValid = bool(sensor_data_age < 5.0) params.liveParameters.angleOffset = float(math.degrees(learner.ao)) params.liveParameters.angleOffsetAverage = float(math.degrees(learner.slow_ao)) params.liveParameters.stiffnessFactor = float(learner.x) @@ -245,8 +254,9 @@ def locationd_thread(gctx, addr, disabled_logs): if i % 6000 == 0: # once a minute params = learner.get_values() params['carFingerprint'] = CP.carFingerprint + params['carVin'] = CP.carVin params_reader.put("LiveParameters", json.dumps(params)) - params_reader.put("ControlsParams", json.dumps({'angle_model_bias': log.live100.angleModelBias})) + params_reader.put("ControlsParams", json.dumps({'angle_model_bias': log.controlsState.angleModelBias})) i += 1 elif socket is camera_odometry_socket: @@ -264,7 +274,7 @@ def main(gctx=None, addr="127.0.0.1"): disabled_logs = os.getenv("DISABLED_LOGS", "").split(",") # No speed for now - disabled_logs.append('live100') + disabled_logs.append('controlsState') if IN_CAR: addr = "192.168.5.11" diff --git a/selfdrive/locationd/ubloxd_main.cc b/selfdrive/locationd/ubloxd_main.cc index 1cfb8c5fb..3ea080ad9 100644 --- a/selfdrive/locationd/ubloxd_main.cc +++ b/selfdrive/locationd/ubloxd_main.cc @@ -72,7 +72,7 @@ int ubloxd_main(poll_ubloxraw_msg_func poll_func, send_gps_event_func send_func) // New message available if(parser.msg_class() == CLASS_NAV) { if(parser.msg_id() == MSG_NAV_PVT) { - LOGD("MSG_NAV_PVT"); + //LOGD("MSG_NAV_PVT"); auto words = parser.gen_solution(); if(words.size() > 0) { auto bytes = words.asBytes(); @@ -82,14 +82,14 @@ int ubloxd_main(poll_ubloxraw_msg_func poll_func, send_gps_event_func send_func) LOGW("Unknown nav msg id: 0x%02X", parser.msg_id()); } else if(parser.msg_class() == CLASS_RXM) { if(parser.msg_id() == MSG_RXM_RAW) { - LOGD("MSG_RXM_RAW"); + //LOGD("MSG_RXM_RAW"); auto words = parser.gen_raw(); if(words.size() > 0) { auto bytes = words.asBytes(); send_func(parser.msg_class(), parser.msg_id(), ubloxGnss, bytes.begin(), bytes.size(), 0); } } else if(parser.msg_id() == MSG_RXM_SFRBX) { - LOGD("MSG_RXM_SFRBX"); + //LOGD("MSG_RXM_SFRBX"); auto words = parser.gen_nav_data(); if(words.size() > 0) { auto bytes = words.asBytes(); diff --git a/selfdrive/loggerd/config.py b/selfdrive/loggerd/config.py index 9d1c3120f..14e1e67a9 100644 --- a/selfdrive/loggerd/config.py +++ b/selfdrive/loggerd/config.py @@ -7,3 +7,13 @@ else: ROOT = '/data/media/0/realdata/' SEGMENT_LENGTH = 60 + + +def get_available_percent(): + try: + statvfs = os.statvfs(ROOT) + available_percent = 100.0 * statvfs.f_bavail / statvfs.f_blocks + except OSError: + available_percent = 100.0 + + return available_percent diff --git a/selfdrive/loggerd/deleter.py b/selfdrive/loggerd/deleter.py index 01a91d774..86974a00c 100644 --- a/selfdrive/loggerd/deleter.py +++ b/selfdrive/loggerd/deleter.py @@ -3,14 +3,13 @@ import os import shutil import threading from selfdrive.swaglog import cloudlog -from selfdrive.loggerd.config import ROOT +from selfdrive.loggerd.config import ROOT, get_available_percent from selfdrive.loggerd.uploader import listdir_by_creation_date def deleter_thread(exit_event): while not exit_event.is_set(): - statvfs = os.statvfs(ROOT) - available_percent = 100.0 * statvfs.f_bavail / statvfs.f_blocks + available_percent = get_available_percent() if available_percent < 10.0: # remove the earliest directory we can diff --git a/selfdrive/loggerd/loggerd b/selfdrive/loggerd/loggerd index 110aafbb3..2fcf09831 100755 Binary files a/selfdrive/loggerd/loggerd and b/selfdrive/loggerd/loggerd differ diff --git a/selfdrive/loggerd/tests/fill_eon.py b/selfdrive/loggerd/tests/fill_eon.py index 2385e3aa5..8ebc5ceb2 100755 --- a/selfdrive/loggerd/tests/fill_eon.py +++ b/selfdrive/loggerd/tests/fill_eon.py @@ -3,7 +3,7 @@ import os -from selfdrive.loggerd.config import ROOT +from selfdrive.loggerd.config import ROOT, get_available_percent from selfdrive.loggerd.tests.loggerd_tests_common import create_random_file @@ -21,7 +21,6 @@ if __name__ == "__main__": segment_idx += 1 # Fill up to 99 percent - statvfs = os.statvfs(ROOT) - available_percent = 100.0 * statvfs.f_bavail / statvfs.f_blocks + available_percent = get_available_percent() if available_percent < 1.0: break diff --git a/selfdrive/logmessaged.py b/selfdrive/logmessaged.py index 971db8293..fb4a2bedf 100755 --- a/selfdrive/logmessaged.py +++ b/selfdrive/logmessaged.py @@ -28,6 +28,7 @@ def main(gctx): if levelnum >= le_level: # push to logentries + # TODO: push to athena instead le_handler.emit_raw(dat) # then we publish them diff --git a/selfdrive/manager.py b/selfdrive/manager.py index 6dcd982f7..30e413c30 100755 --- a/selfdrive/manager.py +++ b/selfdrive/manager.py @@ -93,7 +93,6 @@ managed_processes = { "plannerd": "selfdrive.controls.plannerd", "radard": "selfdrive.controls.radard", "ubloxd": ("selfdrive/locationd", ["./ubloxd"]), - "mapd": "selfdrive.mapd.mapd", "loggerd": ("selfdrive/loggerd", ["./loggerd"]), "logmessaged": "selfdrive.logmessaged", "tombstoned": "selfdrive.tombstoned", @@ -101,7 +100,7 @@ managed_processes = { "proclogd": ("selfdrive/proclogd", ["./proclogd"]), "boardd": ("selfdrive/boardd", ["./boardd"]), # not used directly "pandad": "selfdrive.pandad", - "ui": ("selfdrive/ui", ["./start.sh"]), + "ui": ("selfdrive/ui", ["./start.py"]), "calibrationd": "selfdrive.locationd.calibrationd", "locationd": "selfdrive.locationd.locationd_local", "visiond": ("selfdrive/visiond", ["./visiond"]), @@ -128,11 +127,9 @@ persistent_processes = [ 'logcatd', 'tombstoned', 'uploader', - 'deleter', 'ui', - 'gpsd', 'updated', - 'athena' + 'athena', ] car_started_processes = [ @@ -146,7 +143,8 @@ car_started_processes = [ 'visiond', 'proclogd', 'ubloxd', - 'mapd', + 'gpsd', + 'deleter', ] def register_managed_process(name, desc, car_started=False): @@ -318,6 +316,7 @@ def manager_thread(): # save boot log subprocess.call(["./loggerd", "--bootlog"], cwd=os.path.join(BASEDIR, "selfdrive/loggerd")) + # start persistent processes for p in persistent_processes: start_managed_process(p) @@ -356,8 +355,8 @@ def manager_thread(): kill_managed_process(p) # check the status of all processes, did any of them die? - for p in running: - cloudlog.debug(" running %s %s" % (p, running[p])) + running_list = [" running %s %s" % (p, running[p]) for p in running] + cloudlog.debug('\n'.join(running_list)) # is this still needed? if params.get("DoUninstall") == "1": diff --git a/selfdrive/mapd/default_speeds.json b/selfdrive/mapd/default_speeds.json deleted file mode 100644 index 7126c27fc..000000000 --- a/selfdrive/mapd/default_speeds.json +++ /dev/null @@ -1,106 +0,0 @@ -{ - "_comment": "These speeds are from https://wiki.openstreetmap.org/wiki/Speed_limits Special cases have been stripped", - "AR:urban": "40", - "AR:urban:primary": "60", - "AR:urban:secondary": "60", - "AR:rural": "110", - "AT:urban": "50", - "AT:rural": "100", - "AT:trunk": "100", - "AT:motorway": "130", - "BE:urban": "50", - "BE-VLG:rural": "70", - "BE-WAL:rural": "90", - "BE:trunk": "120", - "BE:motorway": "120", - "CH:urban[1]": "50", - "CH:rural": "80", - "CH:trunk": "100", - "CH:motorway": "120", - "CZ:pedestrian_zone": "20", - "CZ:living_street": "20", - "CZ:urban": "50", - "CZ:urban_trunk": "80", - "CZ:urban_motorway": "80", - "CZ:rural": "90", - "CZ:trunk": "110", - "CZ:motorway": "130", - "DK:urban": "50", - "DK:rural": "80", - "DK:motorway": "130", - "DE:living_street": "7", - "DE:residential": "30", - "DE:urban": "50", - "DE:rural": "100", - "DE:trunk": "none", - "DE:motorway": "none", - "FI:urban": "50", - "FI:rural": "80", - "FI:trunk": "100", - "FI:motorway": "120", - "FR:urban": "50", - "FR:rural": "80", - "FR:trunk": "110", - "FR:motorway": "130", - "GR:urban": "50", - "GR:rural": "90", - "GR:trunk": "110", - "GR:motorway": "130", - "HU:urban": "50", - "HU:rural": "90", - "HU:trunk": "110", - "HU:motorway": "130", - "IT:urban": "50", - "IT:rural": "90", - "IT:trunk": "110", - "IT:motorway": "130", - "JP:national": "60", - "JP:motorway": "100", - "LT:living_street": "20", - "LT:urban": "50", - "LT:rural": "90", - "LT:trunk": "120", - "LT:motorway": "130", - "PL:living_street": "20", - "PL:urban": "50", - "PL:rural": "90", - "PL:trunk": "100", - "PL:motorway": "140", - "RO:urban": "50", - "RO:rural": "90", - "RO:trunk": "100", - "RO:motorway": "130", - "RU:living_street": "20", - "RU:urban": "60", - "RU:rural": "90", - "RU:motorway": "110", - "SK:urban": "50", - "SK:rural": "90", - "SK:trunk": "90", - "SK:motorway": "90", - "SI:urban": "50", - "SI:rural": "90", - "SI:trunk": "110", - "SI:motorway": "130", - "ES:living_street": "20", - "ES:urban": "50", - "ES:rural": "50", - "ES:trunk": "90", - "ES:motorway": "120", - "SE:urban": "50", - "SE:rural": "70", - "SE:trunk": "90", - "SE:motorway": "110", - "GB:nsl_restricted": "30 mph", - "GB:nsl_single": "60 mph", - "GB:nsl_dual": "70 mph", - "GB:motorway": "70 mph", - "UA:urban": "50", - "UA:rural": "90", - "UA:trunk": "110", - "UA:motorway": "130", - "UZ:living_street": "30", - "UZ:urban": "70", - "UZ:rural": "100", - "UZ:motorway": "110" -} diff --git a/selfdrive/mapd/default_speeds_generator.py b/selfdrive/mapd/default_speeds_generator.py deleted file mode 100755 index 888c9e1df..000000000 --- a/selfdrive/mapd/default_speeds_generator.py +++ /dev/null @@ -1,240 +0,0 @@ -#!/usr/bin/env python -import json - -DEFAULT_OUTPUT_FILENAME = "default_speeds_by_region.json" - -def main(filename = DEFAULT_OUTPUT_FILENAME): - countries = [] - - """ - -------------------------------------------------- - US - United State of America - -------------------------------------------------- - """ - US = Country("US") # First step, create the country using the ISO 3166 two letter code - countries.append(US) # Second step, add the country to countries list - - """ Default rules """ - # Third step, add some default rules for the country - # Speed limit rules are based on OpenStreetMaps (OSM) tags. - # The dictionary {...} defines the tag_name: value - # if a road in OSM has a tag with the name tag_name and this value, the speed limit listed below will be applied. - # The text at the end is the speed limit (use no unit for km/h) - # Rules apply in the order in which they are written for each country - # Rules for specific regions (states) take priority over country rules - # If you modify existing country rules, you must update all existing states without that rule to use the old rule - US.add_rule({"highway": "motorway"}, "65 mph") # On US roads with the tag highway and value motorway, the speed limit will default to 65 mph - US.add_rule({"highway": "trunk"}, "55 mph") - US.add_rule({"highway": "primary"}, "55 mph") - US.add_rule({"highway": "secondary"}, "45 mph") - US.add_rule({"highway": "tertiary"}, "35 mph") - US.add_rule({"highway": "unclassified"}, "55 mph") - US.add_rule({"highway": "residential"}, "25 mph") - US.add_rule({"highway": "service"}, "25 mph") - US.add_rule({"highway": "motorway_link"}, "55 mph") - US.add_rule({"highway": "trunk_link"}, "55 mph") - US.add_rule({"highway": "primary_link"}, "55 mph") - US.add_rule({"highway": "secondary_link"}, "45 mph") - US.add_rule({"highway": "tertiary_link"}, "35 mph") - US.add_rule({"highway": "living_street"}, "15 mph") - - """ States """ - new_york = US.add_region("New York") # Fourth step, add a state/region to country - new_york.add_rule({"highway": "primary"}, "45 mph") # Fifth step , add rules to the state. See the text above for how to write rules - new_york.add_rule({"highway": "secondary"}, "55 mph") - new_york.add_rule({"highway": "tertiary"}, "55 mph") - new_york.add_rule({"highway": "residential"}, "30 mph") - new_york.add_rule({"highway": "primary_link"}, "45 mph") - new_york.add_rule({"highway": "secondary_link"}, "55 mph") - new_york.add_rule({"highway": "tertiary_link"}, "55 mph") - # All if not written by the state, the rules will default to the country rules - - #california = US.add_region("California") - # California uses only the default US rules - - michigan = US.add_region("Michigan") - michigan.add_rule({"highway": "motorway"}, "70 mph") - - oregon = US.add_region("Oregon") - oregon.add_rule({"highway": "motorway"}, "55 mph") - oregon.add_rule({"highway": "secondary"}, "35 mph") - oregon.add_rule({"highway": "tertiary"}, "30 mph") - oregon.add_rule({"highway": "service"}, "15 mph") - oregon.add_rule({"highway": "secondary_link"}, "35 mph") - oregon.add_rule({"highway": "tertiary_link"}, "30 mph") - - south_dakota = US.add_region("South Dakota") - south_dakota.add_rule({"highway": "motorway"}, "80 mph") - south_dakota.add_rule({"highway": "trunk"}, "70 mph") - south_dakota.add_rule({"highway": "primary"}, "65 mph") - south_dakota.add_rule({"highway": "trunk_link"}, "70 mph") - south_dakota.add_rule({"highway": "primary_link"}, "65 mph") - - wisconsin = US.add_region("Wisconsin") - wisconsin.add_rule({"highway": "trunk"}, "65 mph") - wisconsin.add_rule({"highway": "tertiary"}, "45 mph") - wisconsin.add_rule({"highway": "unclassified"}, "35 mph") - wisconsin.add_rule({"highway": "trunk_link"}, "65 mph") - wisconsin.add_rule({"highway": "tertiary_link"}, "45 mph") - - """ - -------------------------------------------------- - AU - Australia - -------------------------------------------------- - """ - AU = Country("AU") - countries.append(AU) - - """ Default rules """ - AU.add_rule({"highway": "motorway"}, "100") - AU.add_rule({"highway": "trunk"}, "80") - AU.add_rule({"highway": "primary"}, "80") - AU.add_rule({"highway": "secondary"}, "50") - AU.add_rule({"highway": "tertiary"}, "50") - AU.add_rule({"highway": "unclassified"}, "80") - AU.add_rule({"highway": "residential"}, "50") - AU.add_rule({"highway": "service"}, "40") - AU.add_rule({"highway": "motorway_link"}, "90") - AU.add_rule({"highway": "trunk_link"}, "80") - AU.add_rule({"highway": "primary_link"}, "80") - AU.add_rule({"highway": "secondary_link"}, "50") - AU.add_rule({"highway": "tertiary_link"}, "50") - AU.add_rule({"highway": "living_street"}, "30") - - """ - -------------------------------------------------- - CA - Canada - -------------------------------------------------- - """ - CA = Country("CA") - countries.append(CA) - - """ Default rules """ - CA.add_rule({"highway": "motorway"}, "100") - CA.add_rule({"highway": "trunk"}, "80") - CA.add_rule({"highway": "primary"}, "80") - CA.add_rule({"highway": "secondary"}, "50") - CA.add_rule({"highway": "tertiary"}, "50") - CA.add_rule({"highway": "unclassified"}, "80") - CA.add_rule({"highway": "residential"}, "40") - CA.add_rule({"highway": "service"}, "40") - CA.add_rule({"highway": "motorway_link"}, "90") - CA.add_rule({"highway": "trunk_link"}, "80") - CA.add_rule({"highway": "primary_link"}, "80") - CA.add_rule({"highway": "secondary_link"}, "50") - CA.add_rule({"highway": "tertiary_link"}, "50") - CA.add_rule({"highway": "living_street"}, "20") - - - """ - -------------------------------------------------- - DE - Germany - -------------------------------------------------- - """ - DE = Country("DE") - countries.append(DE) - - """ Default rules """ - DE.add_rule({"highway": "motorway"}, "none") - DE.add_rule({"highway": "living_street"}, "10") - DE.add_rule({"highway": "residential"}, "30") - DE.add_rule({"zone:traffic": "DE:rural"}, "100") - DE.add_rule({"zone:traffic": "DE:urban"}, "50") - DE.add_rule({"zone:maxspeed": "DE:30"}, "30") - DE.add_rule({"zone:maxspeed": "DE:urban"}, "50") - DE.add_rule({"zone:maxspeed": "DE:rural"}, "100") - DE.add_rule({"zone:maxspeed": "DE:motorway"}, "none") - DE.add_rule({"bicycle_road": "yes"}, "30") - - - """ - -------------------------------------------------- - EE - Estonia - -------------------------------------------------- - """ - EE = Country("EE") - countries.append(EE) - - """ Default rules """ - EE.add_rule({"highway": "motorway"}, "90") - EE.add_rule({"highway": "trunk"}, "90") - EE.add_rule({"highway": "primary"}, "90") - EE.add_rule({"highway": "secondary"}, "50") - EE.add_rule({"highway": "tertiary"}, "50") - EE.add_rule({"highway": "unclassified"}, "90") - EE.add_rule({"highway": "residential"}, "40") - EE.add_rule({"highway": "service"}, "40") - EE.add_rule({"highway": "motorway_link"}, "90") - EE.add_rule({"highway": "trunk_link"}, "70") - EE.add_rule({"highway": "primary_link"}, "70") - EE.add_rule({"highway": "secondary_link"}, "50") - EE.add_rule({"highway": "tertiary_link"}, "50") - EE.add_rule({"highway": "living_street"}, "20") - - - """ --- DO NOT MODIFY CODE BELOW THIS LINE --- """ - """ --- ADD YOUR COUNTRY OR STATE ABOVE --- """ - - # Final step - write_json(countries, filename) - -def write_json(countries, filename = DEFAULT_OUTPUT_FILENAME): - out_dict = {} - for country in countries: - out_dict.update(country.jsonify()) - json_string = json.dumps(out_dict, indent=2) - with open(filename, "wb") as f: - f.write(json_string) - - -class Region(object): - ALLOWABLE_TAG_KEYS = ["highway", "zone:traffic", "bicycle_road", "zone:maxspeed"] - ALLOWABLE_HIGHWAY_TYPES = ["motorway", "trunk", "primary", "secondary", "tertiary", "unclassified", "residential", "service", "motorway_link", "trunk_link", "primary_link", "secondary_link", "tertiary_link", "living_street"] - def __init__(self, name): - self.name = name - self.rules = [] - - def add_rule(self, tag_conditions, speed): - new_rule = {} - if not isinstance(tag_conditions, dict): - raise TypeError("Rule tag conditions must be dictionary") - if not all(tag_key in self.ALLOWABLE_TAG_KEYS for tag_key in tag_conditions): - raise ValueError("Rule tag keys must be in allowable tag kesy") # If this is by mistake, please update ALLOWABLE_TAG_KEYS - if 'highway' in tag_conditions: - if not tag_conditions['highway'] in self.ALLOWABLE_HIGHWAY_TYPES: - raise ValueError("Invalid Highway type {}".format(tag_conditions["highway"])) - new_rule['tags'] = tag_conditions - try: - new_rule['speed'] = str(speed) - except ValueError: - raise ValueError("Rule speed must be string") - self.rules.append(new_rule) - - def jsonify(self): - ret_dict = {} - ret_dict[self.name] = self.rules - return ret_dict - -class Country(Region): - ALLOWABLE_COUNTRY_CODES = ["AF","AX","AL","DZ","AS","AD","AO","AI","AQ","AG","AR","AM","AW","AU","AT","AZ","BS","BH","BD","BB","BY","BE","BZ","BJ","BM","BT","BO","BQ","BA","BW","BV","BR","IO","BN","BG","BF","BI","KH","CM","CA","CV","KY","CF","TD","CL","CN","CX","CC","CO","KM","CG","CD","CK","CR","CI","HR","CU","CW","CY","CZ","DK","DJ","DM","DO","EC","EG","SV","GQ","ER","EE","ET","FK","FO","FJ","FI","FR","GF","PF","TF","GA","GM","GE","DE","GH","GI","GR","GL","GD","GP","GU","GT","GG","GN","GW","GY","HT","HM","VA","HN","HK","HU","IS","IN","ID","IR","IQ","IE","IM","IL","IT","JM","JP","JE","JO","KZ","KE","KI","KP","KR","KW","KG","LA","LV","LB","LS","LR","LY","LI","LT","LU","MO","MK","MG","MW","MY","MV","ML","MT","MH","MQ","MR","MU","YT","MX","FM","MD","MC","MN","ME","MS","MA","MZ","MM","NA","NR","NP","NL","NC","NZ","NI","NE","NG","NU","NF","MP","NO","OM","PK","PW","PS","PA","PG","PY","PE","PH","PN","PL","PT","PR","QA","RE","RO","RU","RW","BL","SH","KN","LC","MF","PM","VC","WS","SM","ST","SA","SN","RS","SC","SL","SG","SX","SK","SI","SB","SO","ZA","GS","SS","ES","LK","SD","SR","SJ","SZ","SE","CH","SY","TW","TJ","TZ","TH","TL","TG","TK","TO","TT","TN","TR","TM","TC","TV","UG","UA","AE","GB","US","UM","UY","UZ","VU","VE","VN","VG","VI","WF","EH","YE","ZM","ZW"] - def __init__(self, ISO_3166_alpha_2): - Region.__init__(self, ISO_3166_alpha_2) - if ISO_3166_alpha_2 not in self.ALLOWABLE_COUNTRY_CODES: - raise ValueError("Not valid IOS 3166 country code") - self.regions = {} - - def add_region(self, name): - self.regions[name] = Region(name) - return self.regions[name] - - def jsonify(self): - ret_dict = {} - ret_dict[self.name] = {} - for r_name, region in self.regions.items(): - ret_dict[self.name].update(region.jsonify()) - ret_dict[self.name]['Default'] = self.rules - return ret_dict - - -if __name__ == '__main__': - main() diff --git a/selfdrive/mapd/mapd.py b/selfdrive/mapd/mapd.py deleted file mode 100755 index b123fc68b..000000000 --- a/selfdrive/mapd/mapd.py +++ /dev/null @@ -1,297 +0,0 @@ -#!/usr/bin/env python - -# Add phonelibs openblas to LD_LIBRARY_PATH if import fails -from common.basedir import BASEDIR -try: - from scipy import spatial -except ImportError as e: - import os - import sys - - - openblas_path = os.path.join(BASEDIR, "phonelibs/openblas/") - os.environ['LD_LIBRARY_PATH'] += ':' + openblas_path - - args = [sys.executable] - args.extend(sys.argv) - os.execv(sys.executable, args) - -DEFAULT_SPEEDS_BY_REGION_JSON_FILE = BASEDIR + "/selfdrive/mapd/default_speeds_by_region.json" -from selfdrive.mapd import default_speeds_generator -default_speeds_generator.main(DEFAULT_SPEEDS_BY_REGION_JSON_FILE) - -import os -import sys -import time -import zmq -import threading -import numpy as np -import overpy -from collections import defaultdict - -from common.params import Params -from common.transformations.coordinates import geodetic2ecef -from selfdrive.services import service_list -import selfdrive.messaging as messaging -from selfdrive.mapd.mapd_helpers import MAPS_LOOKAHEAD_DISTANCE, Way, circle_through_points -import selfdrive.crash as crash -from selfdrive.version import version, dirty - - -OVERPASS_API_URL = "https://overpass.kumi.systems/api/interpreter" -OVERPASS_HEADERS = { - 'User-Agent': 'NEOS (comma.ai)', - 'Accept-Encoding': 'gzip' -} - -last_gps = None -query_lock = threading.Lock() -last_query_result = None -last_query_pos = None -cache_valid = False - -def build_way_query(lat, lon, radius=50): - """Builds a query to find all highways within a given radius around a point""" - pos = " (around:%f,%f,%f)" % (radius, lat, lon) - lat_lon = "(%f,%f)" % (lat, lon) - q = """( - way - """ + pos + """ - [highway][highway!~"^(footway|path|bridleway|steps|cycleway|construction|bus_guideway|escape)$"]; - >;);out;""" + """is_in""" + lat_lon + """;area._[admin_level~"[24]"]; - convert area ::id = id(), admin_level = t['admin_level'], - name = t['name'], "ISO3166-1:alpha2" = t['ISO3166-1:alpha2'];out; - """ - return q - - -def query_thread(): - global last_query_result, last_query_pos, cache_valid - api = overpy.Overpass(url=OVERPASS_API_URL, headers=OVERPASS_HEADERS, timeout=10.) - - while True: - time.sleep(1) - if last_gps is not None: - fix_ok = last_gps.flags & 1 - if not fix_ok: - continue - - if last_query_pos is not None: - cur_ecef = geodetic2ecef((last_gps.latitude, last_gps.longitude, last_gps.altitude)) - prev_ecef = geodetic2ecef((last_query_pos.latitude, last_query_pos.longitude, last_query_pos.altitude)) - dist = np.linalg.norm(cur_ecef - prev_ecef) - if dist < 1000: #updated when we are 1km from the edge of the downloaded circle - continue - - if dist > 3000: - cache_valid = False - - q = build_way_query(last_gps.latitude, last_gps.longitude, radius=3000) - try: - new_result = api.query(q) - - # Build kd-tree - nodes = [] - real_nodes = [] - node_to_way = defaultdict(list) - location_info = {} - - for n in new_result.nodes: - nodes.append((float(n.lat), float(n.lon), 0)) - real_nodes.append(n) - - for way in new_result.ways: - for n in way.nodes: - node_to_way[n.id].append(way) - - for area in new_result.areas: - if area.tags.get('admin_level', '') == "2": - location_info['country'] = area.tags.get('ISO3166-1:alpha2', '') - if area.tags.get('admin_level', '') == "4": - location_info['region'] = area.tags.get('name', '') - - nodes = np.asarray(nodes) - nodes = geodetic2ecef(nodes) - tree = spatial.cKDTree(nodes) - - query_lock.acquire() - last_query_result = new_result, tree, real_nodes, node_to_way, location_info - last_query_pos = last_gps - cache_valid = True - query_lock.release() - - except Exception as e: - print(e) - query_lock.acquire() - last_query_result = None - query_lock.release() - - -def mapsd_thread(): - global last_gps - - context = zmq.Context() - gps_sock = messaging.sub_sock(context, service_list['gpsLocation'].port, conflate=True) - gps_external_sock = messaging.sub_sock(context, service_list['gpsLocationExternal'].port, conflate=True) - map_data_sock = messaging.pub_sock(context, service_list['liveMapData'].port) - - cur_way = None - curvature_valid = False - curvature = None - upcoming_curvature = 0. - dist_to_turn = 0. - road_points = None - - while True: - gps = messaging.recv_one(gps_sock) - gps_ext = messaging.recv_one_or_none(gps_external_sock) - - if gps_ext is not None: - gps = gps_ext.gpsLocationExternal - else: - gps = gps.gpsLocation - - last_gps = gps - - fix_ok = gps.flags & 1 - if not fix_ok or last_query_result is None or not cache_valid: - cur_way = None - curvature = None - curvature_valid = False - upcoming_curvature = 0. - dist_to_turn = 0. - road_points = None - map_valid = False - else: - map_valid = True - lat = gps.latitude - lon = gps.longitude - heading = gps.bearing - speed = gps.speed - - query_lock.acquire() - cur_way = Way.closest(last_query_result, lat, lon, heading, cur_way) - if cur_way is not None: - pnts, curvature_valid = cur_way.get_lookahead(lat, lon, heading, MAPS_LOOKAHEAD_DISTANCE) - - xs = pnts[:, 0] - ys = pnts[:, 1] - road_points = [float(x) for x in xs], [float(y) for y in ys] - - if speed < 10: - curvature_valid = False - if curvature_valid and pnts.shape[0] <= 3: - curvature_valid = False - - # The curvature is valid when at least MAPS_LOOKAHEAD_DISTANCE of road is found - if curvature_valid: - # Compute the curvature for each point - with np.errstate(divide='ignore'): - circles = [circle_through_points(*p) for p in zip(pnts, pnts[1:], pnts[2:])] - circles = np.asarray(circles) - radii = np.nan_to_num(circles[:, 2]) - radii[radii < 10] = np.inf - curvature = 1. / radii - - # Index of closest point - closest = np.argmin(np.linalg.norm(pnts, axis=1)) - dist_to_closest = pnts[closest, 0] # We can use x distance here since it should be close - - # Compute distance along path - dists = list() - dists.append(0) - for p, p_prev in zip(pnts, pnts[1:, :]): - dists.append(dists[-1] + np.linalg.norm(p - p_prev)) - dists = np.asarray(dists) - dists = dists - dists[closest] + dist_to_closest - dists = dists[1:-1] - - close_idx = np.logical_and(dists > 0, dists < 500) - dists = dists[close_idx] - curvature = curvature[close_idx] - - if len(curvature): - # TODO: Determine left or right turn - curvature = np.nan_to_num(curvature) - - # Outlier rejection - new_curvature = np.percentile(curvature, 90, interpolation='lower') - - k = 0.6 - upcoming_curvature = k * upcoming_curvature + (1 - k) * new_curvature - in_turn_indices = curvature > 0.8 * new_curvature - - if np.any(in_turn_indices): - dist_to_turn = np.min(dists[in_turn_indices]) - else: - dist_to_turn = 999 - else: - upcoming_curvature = 0. - dist_to_turn = 999 - - query_lock.release() - - dat = messaging.new_message() - dat.init('liveMapData') - - if last_gps is not None: - dat.liveMapData.lastGps = last_gps - - if cur_way is not None: - dat.liveMapData.wayId = cur_way.id - - # Speed limit - max_speed = cur_way.max_speed() - if max_speed is not None: - dat.liveMapData.speedLimitValid = True - dat.liveMapData.speedLimit = max_speed - - # TODO: use the function below to anticipate upcoming speed limits - #max_speed_ahead, max_speed_ahead_dist = cur_way.max_speed_ahead(max_speed, lat, lon, heading, MAPS_LOOKAHEAD_DISTANCE) - #if max_speed_ahead is not None and max_speed_ahead_dist is not None: - # dat.liveMapData.speedLimitAheadValid = True - # dat.liveMapData.speedLimitAhead = float(max_speed_ahead) - # dat.liveMapData.speedLimitAheadDistance = float(max_speed_ahead_dist) - - - advisory_max_speed = cur_way.advisory_max_speed() - if advisory_max_speed is not None: - dat.liveMapData.speedAdvisoryValid = True - dat.liveMapData.speedAdvisory = advisory_max_speed - - # Curvature - dat.liveMapData.curvatureValid = curvature_valid - dat.liveMapData.curvature = float(upcoming_curvature) - dat.liveMapData.distToTurn = float(dist_to_turn) - if road_points is not None: - dat.liveMapData.roadX, dat.liveMapData.roadY = road_points - if curvature is not None: - dat.liveMapData.roadCurvatureX = [float(x) for x in dists] - dat.liveMapData.roadCurvature = [float(x) for x in curvature] - - dat.liveMapData.mapValid = map_valid - - map_data_sock.send(dat.to_bytes()) - - -def main(gctx=None): - params = Params() - dongle_id = params.get("DongleId") - crash.bind_user(id=dongle_id) - crash.bind_extra(version=version, dirty=dirty, is_eon=True) - crash.install() - - main_thread = threading.Thread(target=mapsd_thread) - main_thread.daemon = True - main_thread.start() - - q_thread = threading.Thread(target=query_thread) - q_thread.daemon = True - q_thread.start() - - while True: - time.sleep(0.1) - - -if __name__ == "__main__": - main() diff --git a/selfdrive/mapd/mapd_helpers.py b/selfdrive/mapd/mapd_helpers.py deleted file mode 100644 index 58a33ee41..000000000 --- a/selfdrive/mapd/mapd_helpers.py +++ /dev/null @@ -1,364 +0,0 @@ -import math -import json -import numpy as np -from datetime import datetime -from common.basedir import BASEDIR -from selfdrive.config import Conversions as CV -from common.transformations.coordinates import LocalCoord, geodetic2ecef - -LOOKAHEAD_TIME = 10. -MAPS_LOOKAHEAD_DISTANCE = 50 * LOOKAHEAD_TIME - -DEFAULT_SPEEDS_JSON_FILE = BASEDIR + "/selfdrive/mapd/default_speeds.json" -DEFAULT_SPEEDS = {} -with open(DEFAULT_SPEEDS_JSON_FILE, "rb") as f: - DEFAULT_SPEEDS = json.loads(f.read()) - -DEFAULT_SPEEDS_BY_REGION_JSON_FILE = BASEDIR + "/selfdrive/mapd/default_speeds_by_region.json" -DEFAULT_SPEEDS_BY_REGION = {} -with open(DEFAULT_SPEEDS_BY_REGION_JSON_FILE, "rb") as f: - DEFAULT_SPEEDS_BY_REGION = json.loads(f.read()) - -def circle_through_points(p1, p2, p3): - """Fits a circle through three points - Formulas from: http://www.ambrsoft.com/trigocalc/circle3d.htm""" - x1, y1, _ = p1 - x2, y2, _ = p2 - x3, y3, _ = p3 - - A = x1 * (y2 - y3) - y1 * (x2 - x3) + x2 * y3 - x3 * y2 - B = (x1**2 + y1**2) * (y3 - y2) + (x2**2 + y2**2) * (y1 - y3) + (x3**2 + y3**2) * (y2 - y1) - C = (x1**2 + y1**2) * (x2 - x3) + (x2**2 + y2**2) * (x3 - x1) + (x3**2 + y3**2) * (x1 - x2) - D = (x1**2 + y1**2) * (x3 * y2 - x2 * y3) + (x2**2 + y2**2) * (x1 * y3 - x3 * y1) + (x3**2 + y3**2) * (x2 * y1 - x1 * y2) - - return (-B / (2 * A), - C / (2 * A), np.sqrt((B**2 + C**2 - 4 * A * D) / (4 * A**2))) - -def parse_speed_unit(max_speed): - """Converts a maxspeed string to m/s based on the unit present in the input. - OpenStreetMap defaults to kph if no unit is present. """ - - if not max_speed: - return None - - conversion = CV.KPH_TO_MS - if 'mph' in max_speed: - max_speed = max_speed.replace(' mph', '') - conversion = CV.MPH_TO_MS - try: - return float(max_speed) * conversion - except ValueError: - return None - -def parse_speed_tags(tags): - """Parses tags on a way to find the maxspeed string""" - max_speed = None - - if 'maxspeed' in tags: - max_speed = tags['maxspeed'] - - if 'maxspeed:conditional' in tags: - try: - max_speed_cond, cond = tags['maxspeed:conditional'].split(' @ ') - cond = cond[1:-1] - - start, end = cond.split('-') - now = datetime.now() # TODO: Get time and timezone from gps fix so this will work correctly on replays - start = datetime.strptime(start, "%H:%M").replace(year=now.year, month=now.month, day=now.day) - end = datetime.strptime(end, "%H:%M").replace(year=now.year, month=now.month, day=now.day) - - if start <= now <= end: - max_speed = max_speed_cond - except ValueError: - pass - - if not max_speed and 'source:maxspeed' in tags: - max_speed = DEFAULT_SPEEDS.get(tags['source:maxspeed'], None) - if not max_speed and 'maxspeed:type' in tags: - max_speed = DEFAULT_SPEEDS.get(tags['maxspeed:type'], None) - - max_speed = parse_speed_unit(max_speed) - return max_speed - -def geocode_maxspeed(tags, location_info): - max_speed = None - try: - geocode_country = location_info.get('country', '') - geocode_region = location_info.get('region', '') - - country_rules = DEFAULT_SPEEDS_BY_REGION.get(geocode_country, {}) - country_defaults = country_rules.get('Default', []) - for rule in country_defaults: - rule_valid = all( - tag_name in tags - and tags[tag_name] == value - for tag_name, value in rule['tags'].items() - ) - if rule_valid: - max_speed = rule['speed'] - break #stop searching country - - region_rules = country_rules.get(geocode_region, []) - for rule in region_rules: - rule_valid = all( - tag_name in tags - and tags[tag_name] == value - for tag_name, value in rule['tags'].items() - ) - if rule_valid: - max_speed = rule['speed'] - break #stop searching region - except KeyError: - pass - max_speed = parse_speed_unit(max_speed) - return max_speed - -class Way: - def __init__(self, way, query_results): - self.id = way.id - self.way = way - self.query_results = query_results - - points = list() - - for node in self.way.get_nodes(resolve_missing=False): - points.append((float(node.lat), float(node.lon), 0.)) - - self.points = np.asarray(points) - - @classmethod - def closest(cls, query_results, lat, lon, heading, prev_way=None): - results, tree, real_nodes, node_to_way, location_info = query_results - - cur_pos = geodetic2ecef((lat, lon, 0)) - nodes = tree.query_ball_point(cur_pos, 500) - - # If no nodes within 500m, choose closest one - if not nodes: - nodes = [tree.query(cur_pos)[1]] - - ways = [] - for n in nodes: - real_node = real_nodes[n] - ways += node_to_way[real_node.id] - ways = set(ways) - - closest_way = None - best_score = None - for way in ways: - way = Way(way, query_results) - points = way.points_in_car_frame(lat, lon, heading) - - on_way = way.on_way(lat, lon, heading, points) - if not on_way: - continue - - # Create mask of points in front and behind - x = points[:, 0] - y = points[:, 1] - angles = np.arctan2(y, x) - front = np.logical_and((-np.pi / 2) < angles, - angles < (np.pi / 2)) - behind = np.logical_not(front) - - dists = np.linalg.norm(points, axis=1) - - # Get closest point behind the car - dists_behind = np.copy(dists) - dists_behind[front] = np.NaN - closest_behind = points[np.nanargmin(dists_behind)] - - # Get closest point in front of the car - dists_front = np.copy(dists) - dists_front[behind] = np.NaN - closest_front = points[np.nanargmin(dists_front)] - - # fit line: y = a*x + b - x1, y1, _ = closest_behind - x2, y2, _ = closest_front - a = (y2 - y1) / max((x2 - x1), 1e-5) - b = y1 - a * x1 - - # With a factor of 60 a 20m offset causes the same error as a 20 degree heading error - # (A 20 degree heading offset results in an a of about 1/3) - score = abs(a) * 60. + abs(b) - - # Prefer same type of road - if prev_way is not None: - if way.way.tags.get('highway', '') == prev_way.way.tags.get('highway', ''): - score *= 0.5 - - if closest_way is None or score < best_score: - closest_way = way - best_score = score - - # Normal score is < 5 - if best_score > 50: - return None - - return closest_way - - def __str__(self): - return "%s %s" % (self.id, self.way.tags) - - def max_speed(self): - """Extracts the (conditional) speed limit from a way""" - if not self.way: - return None - - max_speed = parse_speed_tags(self.way.tags) - if not max_speed: - location_info = self.query_results[4] - max_speed = geocode_maxspeed(self.way.tags, location_info) - - return max_speed - - def max_speed_ahead(self, current_speed_limit, lat, lon, heading, lookahead): - """Look ahead for a max speed""" - if not self.way: - return None - - speed_ahead = None - speed_ahead_dist = None - lookahead_ways = 5 - way = self - for i in range(lookahead_ways): - way_pts = way.points_in_car_frame(lat, lon, heading) - - # Check current lookahead distance - max_dist = np.linalg.norm(way_pts[-1, :]) - - if max_dist > 2 * lookahead: - break - - if 'maxspeed' in way.way.tags: - spd = parse_speed_tags(way.way.tags) - if not spd: - location_info = self.query_results[4] - spd = geocode_maxspeed(way.way.tags, location_info) - if spd < current_speed_limit: - speed_ahead = spd - min_dist = np.linalg.norm(way_pts[1, :]) - speed_ahead_dist = min_dist - break - # Find next way - way = way.next_way() - if not way: - break - - return speed_ahead, speed_ahead_dist - - def advisory_max_speed(self): - if not self.way: - return None - - tags = self.way.tags - adv_speed = None - - if 'maxspeed:advisory' in tags: - adv_speed = tags['maxspeed:advisory'] - adv_speed = parse_speed_unit(adv_speed) - return adv_speed - - def on_way(self, lat, lon, heading, points=None): - if points is None: - points = self.points_in_car_frame(lat, lon, heading) - x = points[:, 0] - return np.min(x) < 0. and np.max(x) > 0. - - def closest_point(self, lat, lon, heading, points=None): - if points is None: - points = self.points_in_car_frame(lat, lon, heading) - i = np.argmin(np.linalg.norm(points, axis=1)) - return points[i] - - def distance_to_closest_node(self, lat, lon, heading, points=None): - if points is None: - points = self.points_in_car_frame(lat, lon, heading) - return np.min(np.linalg.norm(points, axis=1)) - - def points_in_car_frame(self, lat, lon, heading): - lc = LocalCoord.from_geodetic([lat, lon, 0.]) - - # Build rotation matrix - heading = math.radians(-heading + 90) - c, s = np.cos(heading), np.sin(heading) - rot = np.array([[c, s, 0.], [-s, c, 0.], [0., 0., 1.]]) - - # Convert to local coordinates - points_carframe = lc.geodetic2ned(self.points).T - - # Rotate with heading of car - points_carframe = np.dot(rot, points_carframe[(1, 0, 2), :]).T - - return points_carframe - - def next_way(self, backwards=False): - results, tree, real_nodes, node_to_way, location_info = self.query_results - - if backwards: - node = self.way.nodes[0] - else: - node = self.way.nodes[-1] - - ways = node_to_way[node.id] - - way = None - try: - # Simple heuristic to find next way - ways = [w for w in ways if w.id != self.id] - ways = [w for w in ways if w.nodes[0] == node] - - # Filter on highway tag - acceptable_tags = list() - cur_tag = self.way.tags['highway'] - acceptable_tags.append(cur_tag) - if cur_tag == 'motorway_link': - acceptable_tags.append('motorway') - acceptable_tags.append('trunk') - acceptable_tags.append('primary') - ways = [w for w in ways if w.tags['highway'] in acceptable_tags] - - # Filter on number of lanes - cur_num_lanes = int(self.way.tags['lanes']) - if len(ways) > 1: - ways_same_lanes = [w for w in ways if int(w.tags['lanes']) == cur_num_lanes] - if len(ways_same_lanes) == 1: - ways = ways_same_lanes - if len(ways) > 1: - ways = [w for w in ways if int(w.tags['lanes']) > cur_num_lanes] - if len(ways) == 1: - way = Way(ways[0], self.query_results) - - except (KeyError, ValueError): - pass - - return way - - def get_lookahead(self, lat, lon, heading, lookahead): - pnts = None - way = self - valid = False - - for i in range(5): - # Get new points and append to list - new_pnts = way.points_in_car_frame(lat, lon, heading) - - if pnts is None: - pnts = new_pnts - else: - pnts = np.vstack([pnts, new_pnts]) - - # Check current lookahead distance - max_dist = np.linalg.norm(pnts[-1, :]) - if max_dist > lookahead: - valid = True - - if max_dist > 2 * lookahead: - break - - # Find next way - way = way.next_way() - if not way: - break - - return pnts, valid diff --git a/selfdrive/registration.py b/selfdrive/registration.py index 9b7e6964e..9e4c89b4c 100644 --- a/selfdrive/registration.py +++ b/selfdrive/registration.py @@ -1,10 +1,16 @@ +import os import json import subprocess +import struct +import jwt +from datetime import datetime, timedelta from selfdrive.swaglog import cloudlog -from selfdrive.version import version, training_version +from selfdrive.version import version, training_version, get_git_commit, get_git_branch, get_git_remote from common.api import api_get from common.params import Params +from common.file_helpers import mkdirs_exists_ok + def get_imei(): ret = subprocess.check_output(["getprop", "oem.device.imeicache"]).strip() @@ -12,17 +18,38 @@ def get_imei(): ret = "000000000000000" return ret + def get_serial(): return subprocess.check_output(["getprop", "ro.serialno"]).strip() -def get_git_commit(): - return subprocess.check_output(["git", "rev-parse", "HEAD"]).strip() -def get_git_branch(): - return subprocess.check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"]).strip() +# TODO: move this to a library +def parse_service_call(call): + ret = subprocess.check_output(call).strip() + if 'Parcel' not in ret: + return None + try: + def fh(x): + if len(x) != 8: + return [] + return [x[6:8], x[4:6], x[2:4], x[0:2]] + hd = [] + for x in ret.split("\n")[1:]: + for k in map(fh, x.split(": ")[1].split(" '")[0].split(" ")): + hd.extend(k) + return ''.join([chr(int(x, 16)) for x in hd]) + except Exception: + return None + + +def get_subscriber_info(): + ret = parse_service_call(["service", "call", "iphonesubinfo", "7"]) + if ret is None or len(ret) < 8: + return "" + if struct.unpack("I", ret[4:8]) == -1: + return "" + return ret[8:-2:2] -def get_git_remote(): - return subprocess.check_output(["git", "config", "--get", "remote.origin.url"]).strip() def register(): params = Params() @@ -31,23 +58,42 @@ def register(): params.put("GitCommit", get_git_commit()) params.put("GitBranch", get_git_branch()) params.put("GitRemote", get_git_remote()) + params.put("SubscriberInfo", get_subscriber_info()) + + # create a key for auth + # your private key is kept on your device persist partition and never sent to our servers + # do not erase your persist partition + if not os.path.isfile("/persist/comma/id_rsa.pub"): + cloudlog.warning("generating your personal RSA key") + mkdirs_exists_ok("/persist/comma") + assert os.system("echo -e 'y\n' | ssh-keygen -t rsa -b 2048 -f /persist/comma/id_rsa.tmp -N ''") == 0 + os.rename("/persist/comma/id_rsa.tmp", "/persist/comma/id_rsa") + os.rename("/persist/comma/id_rsa.tmp.pub", "/persist/comma/id_rsa.pub") dongle_id, access_token = params.get("DongleId"), params.get("AccessToken") + public_key = open("/persist/comma/id_rsa.pub").read() + + # create registration token + # in the future, this key will make JWTs directly + private_key = open("/persist/comma/id_rsa").read() + register_token = jwt.encode({'register':True, 'exp': datetime.utcnow() + timedelta(hours=1)}, private_key, algorithm='RS256') try: - if dongle_id is None or access_token is None: - cloudlog.info("getting pilotauth") - resp = api_get("v1/pilotauth/", method='POST', timeout=15, - imei=get_imei(), serial=get_serial()) - dongleauth = json.loads(resp.text) - dongle_id, access_token = dongleauth["dongle_id"].encode('ascii'), dongleauth["access_token"].encode('ascii') + cloudlog.info("getting pilotauth") + resp = api_get("v2/pilotauth/", method='POST', timeout=15, + imei=get_imei(), serial=get_serial(), public_key=public_key, register_token=register_token) + dongleauth = json.loads(resp.text) + dongle_id, access_token = dongleauth["dongle_id"].encode('ascii'), dongleauth["access_token"].encode('ascii') - params.put("DongleId", dongle_id) - params.put("AccessToken", access_token) + params.put("DongleId", dongle_id) + params.put("AccessToken", access_token) return dongle_id, access_token except Exception: cloudlog.exception("failed to authenticate") - return None + if dongle_id is not None and access_token is not None: + return dongle_id, access_token + else: + return None if __name__ == "__main__": print(api_get("").text) diff --git a/selfdrive/sensord/gpsd b/selfdrive/sensord/gpsd index 9d1ef1481..78c105a7d 100755 Binary files a/selfdrive/sensord/gpsd and b/selfdrive/sensord/gpsd differ diff --git a/selfdrive/sensord/sensord b/selfdrive/sensord/sensord index 67edc76ef..df98efc6a 100755 Binary files a/selfdrive/sensord/sensord and b/selfdrive/sensord/sensord differ diff --git a/selfdrive/service_list.yaml b/selfdrive/service_list.yaml index 627d40df8..d18eaf613 100644 --- a/selfdrive/service_list.yaml +++ b/selfdrive/service_list.yaml @@ -14,7 +14,7 @@ gpsNMEA: [8004, true] thermal: [8005, true] # List(CanData), list of can messages can: [8006, true] -live100: [8007, true] +controlsState: [8007, true] # random events we want to log @@ -22,7 +22,7 @@ live100: [8007, true] model: [8009, true] features: [8010, true] health: [8011, true] -live20: [8012, true] +radarState: [8012, true] #liveUI: [8014, true] encodeIdx: [8015, true] liveTracks: [8016, true] @@ -97,23 +97,23 @@ testJoystick: [8056, false] # publishes: sensorEvents, gpsNMEA # visiond -- talks to the cameras, runs the model, saves the videos -# subscribes: liveCalibration, sensorEvents, live100 +# subscribes: liveCalibration, sensorEvents, controlsState # publishes: frame, encodeIdx, model, liveCalibration # **** stateful data transformers **** # plannerd -- decides where to drive the car -# subscribes: carState, model, live20 +# subscribes: carState, model, radarState # publishes: plan # controlsd -- actually drives the car # subscribes: can, thermal, plan -# publishes: carState, carControl, sendcan, live100 +# publishes: carState, carControl, sendcan, controlsState -# radard -- processes the radar data +# radard -- processes the radar and vision data # blocks: CarParams -# subscribes: can, live100, model -# publishes: live20, liveTracks +# subscribes: can, controlsState, model +# publishes: radarState, liveTracks # **** LOGGING SERVICE **** @@ -123,7 +123,7 @@ testJoystick: [8056, false] # **** NON VITAL SERVICES **** # ui -# subscribes: live100, live20, liveCalibration, model, (raw frames) +# subscribes: controlsState, radarState, liveCalibration, model, (raw frames) # uploader # communicates through file system with loggerd diff --git a/selfdrive/test/plant/maneuver.py b/selfdrive/test/plant/maneuver.py index 7ffa50b6c..551fbd0d9 100644 --- a/selfdrive/test/plant/maneuver.py +++ b/selfdrive/test/plant/maneuver.py @@ -28,7 +28,7 @@ class Maneuver(object): distance_lead = self.distance_lead ) - last_live100 = None + last_controls_state = None plot = ManeuverPlot(self.title) buttons_sorted = sorted(self.cruise_button_presses, key=lambda a: a[1]) @@ -42,27 +42,27 @@ class Maneuver(object): grade = np.interp(plant.current_time(), self.grade_breakpoints, self.grade_values) speed_lead = np.interp(plant.current_time(), self.speed_lead_breakpoints, self.speed_lead_values) - distance, speed, acceleration, distance_lead, brake, gas, steer_torque, fcw, live100= plant.step(speed_lead, current_button, grade) - if live100: - last_live100 = live100[-1] + distance, speed, acceleration, distance_lead, brake, gas, steer_torque, fcw, controls_state= plant.step(speed_lead, current_button, grade) + if controls_state: + last_controls_state = controls_state[-1] d_rel = distance_lead - distance if self.lead_relevancy else 200. v_rel = speed_lead - speed if self.lead_relevancy else 0. - if last_live100: - # print(last_live100) + if last_controls_state: + # print(last_controls_state) #develop plots plot.add_data( time=plant.current_time(), gas=gas, brake=brake, steer_torque=steer_torque, distance=distance, speed=speed, acceleration=acceleration, - up_accel_cmd=last_live100.upAccelCmd, ui_accel_cmd=last_live100.uiAccelCmd, - uf_accel_cmd=last_live100.ufAccelCmd, + up_accel_cmd=last_controls_state.upAccelCmd, ui_accel_cmd=last_controls_state.uiAccelCmd, + uf_accel_cmd=last_controls_state.ufAccelCmd, d_rel=d_rel, v_rel=v_rel, v_lead=speed_lead, - v_target_lead=last_live100.vTargetLead, pid_speed=last_live100.vPid, - cruise_speed=last_live100.vCruise, - jerk_factor=last_live100.jerkFactor, - a_target=last_live100.aTarget, + v_target_lead=last_controls_state.vTargetLead, pid_speed=last_controls_state.vPid, + cruise_speed=last_controls_state.vCruise, + jerk_factor=last_controls_state.jerkFactor, + a_target=last_controls_state.aTarget, fcw=fcw) print("maneuver end") diff --git a/selfdrive/test/plant/plant.py b/selfdrive/test/plant/plant.py index 0b86095c5..abe021cd8 100755 --- a/selfdrive/test/plant/plant.py +++ b/selfdrive/test/plant/plant.py @@ -98,7 +98,7 @@ class Plant(object): Plant.sendcan = messaging.sub_sock(context, service_list['sendcan'].port) Plant.model = messaging.pub_sock(context, service_list['model'].port) Plant.cal = messaging.pub_sock(context, service_list['liveCalibration'].port) - Plant.live100 = messaging.sub_sock(context, service_list['live100'].port) + Plant.controls_state = messaging.sub_sock(context, service_list['controlsState'].port) Plant.plan = messaging.sub_sock(context, service_list['plan'].port) Plant.messaging_initialized = True @@ -159,10 +159,10 @@ class Plant(object): can_msgs.extend(can_capnp_to_can_list(a.sendcan, [0,2])) self.cp.update_can(can_msgs) - # ******** get live100 messages for plotting *** - live100_msgs = [] - for a in messaging.drain_sock(Plant.live100): - live100_msgs.append(a.live100) + # ******** get controlsState messages for plotting *** + controls_state_msgs = [] + for a in messaging.drain_sock(Plant.controls_state): + controls_state_msgs.append(a.controlsState) fcw = None for a in messaging.drain_sock(Plant.plan): @@ -241,6 +241,7 @@ class Plant(object): 'EPB_STATE', 'BRAKE_HOLD_ACTIVE', 'INTERCEPTOR_GAS', + 'IMPERIAL_UNIT', ]) vls = vls_tuple( self.speed_sensor(speed), @@ -271,7 +272,8 @@ class Plant(object): self.main_on, 0, # EPB State 0, # Brake hold - 0 # Interceptor feedback + 0, # Interceptor feedback + False ) # TODO: publish each message at proper frequency @@ -351,7 +353,7 @@ class Plant(object): self.distance_lead_prev = distance_lead self.rk.keep_time() - return (distance, speed, acceleration, distance_lead, brake, gas, steer_torque, fcw, live100_msgs) + return (distance, speed, acceleration, distance_lead, brake, gas, steer_torque, fcw, controls_state_msgs) # simple engage in standalone mode def plant_thread(rate=100): diff --git a/selfdrive/thermald.py b/selfdrive/thermald.py index a2c9b20a8..e3c02dc06 100755 --- a/selfdrive/thermald.py +++ b/selfdrive/thermald.py @@ -7,7 +7,7 @@ from selfdrive.version import training_version from selfdrive.swaglog import cloudlog import selfdrive.messaging as messaging from selfdrive.services import service_list -from selfdrive.loggerd.config import ROOT +from selfdrive.loggerd.config import get_available_percent from common.params import Params from common.realtime import sec_since_boot from common.numpy_fast import clip @@ -121,37 +121,6 @@ def check_car_battery_voltage(should_start, health, charging_disabled): return charging_disabled -class LocationStarter(object): - def __init__(self): - self.last_good_loc = 0 - def update(self, started_ts, location): - rt = sec_since_boot() - - if location is None or location.accuracy > 50 or location.speed < 2: - # bad location, stop if we havent gotten a location in a while - # dont stop if we're been going for less than a minute - if started_ts: - if rt-self.last_good_loc > 60. and rt-started_ts > 60: - cloudlog.event("location_stop", - ts=rt, - started_ts=started_ts, - last_good_loc=self.last_good_loc, - location=location.to_dict() if location else None) - return False - else: - return True - else: - return False - - self.last_good_loc = rt - - if started_ts: - return True - else: - cloudlog.event("location_start", location=location.to_dict() if location else None) - return location.speed*3.6 > 10 - - def thermald_thread(): setup_eon_fan() @@ -170,10 +139,10 @@ def thermald_thread(): started_ts = None ignition_seen = False started_seen = False - passive_starter = LocationStarter() thermal_status = ThermalStatus.green health_sock.RCVTIMEO = 1500 current_filter = FirstOrderFilter(0., CURRENT_TAU, 1.) + health_prev = None # Make sure charging is enabled charging_disabled = False @@ -187,9 +156,13 @@ def thermald_thread(): location = location.gpsLocation if location else None msg = read_thermal() + # clear car params when panda gets disconnected + if health is None and health_prev is not None: + params.panda_disconnect() + health_prev = health + # loggerd is gated based on free space - statvfs = os.statvfs(ROOT) - avail = (statvfs.f_bavail * 1.0)/statvfs.f_blocks + avail = get_available_percent() / 100.0 # thermal message now also includes free space msg.thermal.freeSpace = avail @@ -253,17 +226,9 @@ def thermald_thread(): # have we seen a panda? passive = (params.get("Passive") == "1") - # start on gps movement if we haven't seen ignition and are in passive mode - should_start = should_start or (not (ignition_seen and health) # seen ignition and panda is connected - and passive - and passive_starter.update(started_ts, location)) - # with 2% left, we killall, otherwise the phone will take a long time to boot should_start = should_start and msg.thermal.freeSpace > 0.02 - # require usb power in passive mode - should_start = should_start and (not passive or msg.thermal.usbOnline) - # confirm we have completed training and aren't uninstalling should_start = should_start and accepted_terms and (passive or completed_training) and (not do_uninstall) @@ -276,7 +241,6 @@ def thermald_thread(): if should_start: off_ts = None if started_ts is None: - params.car_start() started_ts = sec_since_boot() started_seen = True os.system('echo performance > /sys/class/devfreq/soc:qcom,cpubw/governor') @@ -295,7 +259,7 @@ def thermald_thread(): #charging_disabled = check_car_battery_voltage(should_start, health, charging_disabled) msg.thermal.chargingDisabled = charging_disabled - msg.thermal.chargingError = current_filter.x > 0. # if current is positive, then battery is being discharged + msg.thermal.chargingError = current_filter.x > 0. and msg.thermal.batteryPercent < 90 # if current is positive, then battery is being discharged msg.thermal.started = started_ts is not None msg.thermal.startedTs = int(1e9*(started_ts or 0)) @@ -319,4 +283,3 @@ def main(gctx=None): if __name__ == "__main__": main() - diff --git a/selfdrive/ui/start.py b/selfdrive/ui/start.py new file mode 100755 index 000000000..08bd6217e --- /dev/null +++ b/selfdrive/ui/start.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python +import os + +assert os.system("make") == 0 +os.environ['LD_LIBRARY_PATH'] = "/system/lib64:"+os.environ['LD_LIBRARY_PATH'] +os.execv("./ui", ["ui"]) + diff --git a/selfdrive/ui/start.sh b/selfdrive/ui/start.sh deleted file mode 100755 index 89704a5b6..000000000 --- a/selfdrive/ui/start.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -set -e - -make -export LD_LIBRARY_PATH=/system/lib64:$LD_LIBRARY_PATH -exec ./ui diff --git a/selfdrive/ui/ui.c b/selfdrive/ui/ui.c index dea27ab18..b6a97724c 100644 --- a/selfdrive/ui/ui.c +++ b/selfdrive/ui/ui.c @@ -19,6 +19,7 @@ #include "nanovg_gl.h" #include "nanovg_gl_utils.h" +#include "common/messaging.h" #include "common/timing.h" #include "common/util.h" #include "common/swaglog.h" @@ -48,6 +49,7 @@ #define ALERTSIZE_FULL 3 #define UI_BUF_COUNT 4 +//#define SHOW_SPEEDLIMIT 1 //#define DEBUG_TURN //#define DEBUG_FPS @@ -199,24 +201,17 @@ typedef struct UIState { int img_face; int img_map; - zsock_t *thermal_sock; + void *ctx; + void *thermal_sock_raw; - zsock_t *model_sock; void *model_sock_raw; - zsock_t *live100_sock; - void *live100_sock_raw; - zsock_t *livecalibration_sock; + void *controlsstate_sock_raw; void *livecalibration_sock_raw; - zsock_t *live20_sock; - void *live20_sock_raw; - zsock_t *livempc_sock; + void *radarstate_sock_raw; void *livempc_sock_raw; - zsock_t *plus_sock; void *plus_sock_raw; - zsock_t *map_data_sock; void *map_data_sock_raw; - zsock_t *uilayout_sock; void *uilayout_sock_raw; int plus_state; @@ -261,14 +256,15 @@ typedef struct UIState { int volume_timeout; int speed_lim_off_timeout; int is_metric_timeout; + int longitudinal_control_timeout; int limit_set_speed_timeout; int status; bool is_metric; + bool longitudinal_control; bool limit_set_speed; float speed_lim_off; bool is_ego_over_limit; - bool passive; char alert_type[64]; char alert_sound[64]; int alert_size; @@ -281,7 +277,7 @@ typedef struct UIState { // Hints for re-calculations and redrawing bool model_changed; - bool livempc_or_live20_changed; + bool livempc_or_radarstate_changed; GLuint frame_vao[2], frame_vbo[2], frame_ibo[2]; mat4 rear_frame_mat, front_frame_mat; @@ -289,7 +285,6 @@ typedef struct UIState { model_path_vertices_data model_path_vertices[MODEL_LANE_PATH_CNT * 2]; track_vertices_data track_vertices[2]; - } UIState; static int last_brightness = -1; @@ -312,12 +307,15 @@ static void set_awake(UIState *s, bool awake) { if (s->awake != awake) { s->awake = awake; + // TODO: replace command_awake and command_sleep with direct calls to android if (awake) { - LOG("awake normal"); + LOGW("awake normal"); + system("service call window 18 i32 1"); // enable event processing framebuffer_set_power(s->fb, HWC_POWER_MODE_NORMAL); } else { - LOG("awake off"); + LOGW("awake off"); set_brightness(s, 0); + system("service call window 18 i32 0"); // disable event processing framebuffer_set_power(s->fb, HWC_POWER_MODE_OFF); } } @@ -337,36 +335,42 @@ static void set_do_exit(int sig) { do_exit = 1; } -static void read_speed_lim_off(UIState *s) { - char *speed_lim_off = NULL; - read_db_value(NULL, "SpeedLimitOffset", &speed_lim_off, NULL); - s->speed_lim_off = 0.; - if (speed_lim_off) { - s->speed_lim_off = strtod(speed_lim_off, NULL); - free(speed_lim_off); +static void read_param_bool(bool* param, char* param_name) { + char *s; + const int result = read_db_value(NULL, param_name, &s, NULL); + if (result == 0) { + *param = s[0] == '1'; + free(s); } - s->speed_lim_off_timeout = 2 * UI_FREQ; // 0.5Hz } -static void read_is_metric(UIState *s) { - char *is_metric; - const int result = read_db_value(NULL, "IsMetric", &is_metric, NULL); +static void read_param_float(float* param, char* param_name) { + char *s; + const int result = read_db_value(NULL, param_name, &s, NULL); if (result == 0) { - s->is_metric = is_metric[0] == '1'; - free(is_metric); + *param = strtod(s, NULL); + free(s); } - s->is_metric_timeout = 2 * UI_FREQ; // 0.5Hz } -static void read_limit_set_speed(UIState *s) { - char *limit_set_speed; - const int result = read_db_value(NULL, "LimitSetSpeed", &limit_set_speed, NULL); - if (result == 0) { - s->limit_set_speed = limit_set_speed[0] == '1'; - free(limit_set_speed); +static void read_param_bool_timeout(bool* param, char* param_name, int* timeout) { + if (*timeout > 0){ + (*timeout)--; + } else { + read_param_bool(param, param_name); + *timeout = 2 * UI_FREQ; // 0.5Hz } - s->limit_set_speed_timeout = 2 * UI_FREQ; // 0.2Hz } + +static void read_param_float_timeout(float* param, char* param_name, int* timeout) { + if (*timeout > 0){ + (*timeout)--; + } else { + read_param_float(param, param_name); + *timeout = 2 * UI_FREQ; // 0.5Hz + } +} + static const char frame_vertex_shader[] = "attribute vec4 aPosition;\n" "attribute vec4 aTexCoord;\n" @@ -470,43 +474,20 @@ static void ui_init(UIState *s) { pthread_mutex_init(&s->lock, NULL); pthread_cond_init(&s->bg_cond, NULL); - // init connections + s->ctx = zmq_ctx_new(); - s->thermal_sock = zsock_new_sub(">tcp://127.0.0.1:8005", ""); - assert(s->thermal_sock); - s->thermal_sock_raw = zsock_resolve(s->thermal_sock); + s->thermal_sock_raw = sub_sock(s->ctx, "tcp://127.0.0.1:8005"); + s->model_sock_raw = sub_sock(s->ctx, "tcp://127.0.0.1:8009"); + s->controlsstate_sock_raw = sub_sock(s->ctx, "tcp://127.0.0.1:8007"); + s->uilayout_sock_raw = sub_sock(s->ctx, "tcp://127.0.0.1:8060"); + s->livecalibration_sock_raw = sub_sock(s->ctx, "tcp://127.0.0.1:8019"); + s->radarstate_sock_raw = sub_sock(s->ctx, "tcp://127.0.0.1:8012"); + s->livempc_sock_raw = sub_sock(s->ctx, "tcp://127.0.0.1:8035"); + s->plus_sock_raw = sub_sock(s->ctx, "tcp://127.0.0.1:8037"); - s->model_sock = zsock_new_sub(">tcp://127.0.0.1:8009", ""); - assert(s->model_sock); - s->model_sock_raw = zsock_resolve(s->model_sock); - - s->live100_sock = zsock_new_sub(">tcp://127.0.0.1:8007", ""); - assert(s->live100_sock); - s->live100_sock_raw = zsock_resolve(s->live100_sock); - - s->uilayout_sock = zsock_new_sub(">tcp://127.0.0.1:8060", ""); - assert(s->uilayout_sock); - s->uilayout_sock_raw = zsock_resolve(s->uilayout_sock); - - s->livecalibration_sock = zsock_new_sub(">tcp://127.0.0.1:8019", ""); - assert(s->livecalibration_sock); - s->livecalibration_sock_raw = zsock_resolve(s->livecalibration_sock); - - s->live20_sock = zsock_new_sub(">tcp://127.0.0.1:8012", ""); - assert(s->live20_sock); - s->live20_sock_raw = zsock_resolve(s->live20_sock); - - s->livempc_sock = zsock_new_sub(">tcp://127.0.0.1:8035", ""); - assert(s->livempc_sock); - s->livempc_sock_raw = zsock_resolve(s->livempc_sock); - - s->plus_sock = zsock_new_sub(">tcp://127.0.0.1:8037", ""); - assert(s->plus_sock); - s->plus_sock_raw = zsock_resolve(s->plus_sock); - - s->map_data_sock = zsock_new_sub(">tcp://127.0.0.1:8065", ""); - assert(s->map_data_sock); - s->map_data_sock_raw = zsock_resolve(s->map_data_sock); +#ifdef SHOW_SPEEDLIMIT + s->map_data_sock_raw = sub_sock(s->ctx, "tcp://127.0.0.1:8065"); +#endif s->ipc_fd = -1; @@ -565,14 +546,6 @@ static void ui_init(UIState *s) { assert(glGetError() == GL_NO_ERROR); - { - char *value; - const int result = read_db_value(NULL, "Passive", &value, NULL); - if (result == 0) { - s->passive = value[0] == '1'; - free(value); - } - } for(int i = 0; i < 2; i++) { float x1, x2, y1, y2; if (i == 1) { @@ -614,7 +587,7 @@ static void ui_init(UIState *s) { } s->model_changed = false; - s->livempc_or_live20_changed = false; + s->livempc_or_radarstate_changed = false; s->front_frame_mat = matmul(device_transform, full_to_wide_frame_transform); s->rear_frame_mat = matmul(device_transform, frame_transform); @@ -672,11 +645,15 @@ static void ui_init_vision(UIState *s, const VisionStreamBufs back_bufs, 0.0, 0.0, 0.0, 1.0, }}; - read_speed_lim_off(s); - read_is_metric(s); - read_limit_set_speed(s); - s->is_metric_timeout = UI_FREQ / 2; // offset so values isn't read together with limit offset - s->limit_set_speed_timeout = UI_FREQ; // offset so values isn't read together with limit offset + read_param_float(&s->speed_lim_off, "SpeedLimitOffset"); + read_param_bool(&s->is_metric, "IsMetric"); + read_param_bool(&s->longitudinal_control, "LongitudinalControl"); + read_param_bool(&s->limit_set_speed, "LimitSetSpeed"); + + // Set offsets so params don't get read at the same time + s->longitudinal_control_timeout = UI_FREQ / 3; + s->is_metric_timeout = UI_FREQ / 2; + s->limit_set_speed_timeout = UI_FREQ; } static void ui_draw_transformed_box(UIState *s, uint32_t color) { @@ -1045,9 +1022,9 @@ static void ui_draw_vision_lanes(UIState *s) { pvd + MODEL_LANE_PATH_CNT, nvgRGBAf(1.0, 1.0, 1.0, scene->model.right_lane.prob)); - if(s->livempc_or_live20_changed) { + if(s->livempc_or_radarstate_changed) { update_all_track_data(s); - s->livempc_or_live20_changed = false; + s->livempc_or_radarstate_changed = false; } // Draw vision path ui_draw_track(s, false, &s->track_vertices[0]); @@ -1087,6 +1064,10 @@ static void ui_draw_world(UIState *s) { } static void ui_draw_vision_maxspeed(UIState *s) { + /*if (!s->longitudinal_control){ + return; + }*/ + const UIScene *scene = &s->scene; int ui_viz_rx = scene->ui_viz_rx; int ui_viz_rw = scene->ui_viz_rw; @@ -1113,8 +1094,13 @@ static void ui_draw_vision_maxspeed(UIState *s) { int viz_maxspeed_x = (ui_viz_rx + (bdr_s*2)); int viz_maxspeed_y = (box_y + (bdr_s*1.5)); int viz_maxspeed_xo = 180; + +#ifdef SHOW_SPEEDLIMIT viz_maxspeed_w += viz_maxspeed_xo; viz_maxspeed_x += viz_maxspeed_w - (viz_maxspeed_xo * 2); +#else + viz_maxspeed_xo = 0; +#endif // Draw Background nvgBeginPath(s->vg); @@ -1420,7 +1406,10 @@ static void ui_draw_vision_header(UIState *s) { nvgFill(s->vg); ui_draw_vision_maxspeed(s); + +#ifdef SHOW_SPEEDLIMIT ui_draw_vision_speedlimit(s); +#endif ui_draw_vision_speed(s); ui_draw_vision_event(s); } @@ -1434,7 +1423,10 @@ static void ui_draw_vision_footer(UIState *s) { nvgRect(s->vg, ui_viz_rx, footer_y, ui_viz_rw, footer_h); ui_draw_vision_face(s); + +#ifdef SHOW_SPEEDLIMIT ui_draw_vision_map(s); +#endif } static void ui_draw_vision_alert(UIState *s, int va_size, int va_color, @@ -1511,7 +1503,7 @@ static void ui_draw_vision(UIState *s) { glDisable(GL_SCISSOR_TEST); glClear(GL_STENCIL_BUFFER_BIT); - + nvgBeginFrame(s->vg, s->fb_w, s->fb_h, 1.0f); nvgSave(s->vg); @@ -1746,13 +1738,16 @@ static void ui_update(UIState *s) { } // peek and consume all events in the zmq queue, then return. while(true) { - polls[0].socket = s->live100_sock_raw; + int plus_sock_num = 7; + int num_polls = 8; + + polls[0].socket = s->controlsstate_sock_raw; polls[0].events = ZMQ_POLLIN; polls[1].socket = s->livecalibration_sock_raw; polls[1].events = ZMQ_POLLIN; polls[2].socket = s->model_sock_raw; polls[2].events = ZMQ_POLLIN; - polls[3].socket = s->live20_sock_raw; + polls[3].socket = s->radarstate_sock_raw; polls[3].events = ZMQ_POLLIN; polls[4].socket = s->livempc_sock_raw; polls[4].events = ZMQ_POLLIN; @@ -1760,11 +1755,17 @@ static void ui_update(UIState *s) { polls[5].events = ZMQ_POLLIN; polls[6].socket = s->uilayout_sock_raw; polls[6].events = ZMQ_POLLIN; + +#ifdef SHOW_SPEEDLIMIT + plus_sock_num++; + num_polls++; polls[7].socket = s->map_data_sock_raw; polls[7].events = ZMQ_POLLIN; - polls[8].socket = s->plus_sock_raw; // plus_sock should be last - polls[8].events = ZMQ_POLLIN; - int num_polls = 9; +#endif + + polls[plus_sock_num].socket = s->plus_sock_raw; // plus_sock should be last + polls[plus_sock_num].events = ZMQ_POLLIN; + int ret = zmq_poll(polls, num_polls, 0); if (ret < 0) { LOGW("poll failed (%d)", ret); @@ -1776,12 +1777,12 @@ static void ui_update(UIState *s) { if (polls[0].revents || polls[1].revents || polls[2].revents || polls[3].revents || polls[4].revents || polls[6].revents || - polls[7].revents || polls[8].revents) { + polls[plus_sock_num].revents) { // awake on any (old) activity set_awake(s, true); } - if (polls[8].revents) { + if (polls[plus_sock_num].revents) { // plus socket zmq_msg_t msg; err = zmq_msg_init(&msg); @@ -1822,9 +1823,9 @@ static void ui_update(UIState *s) { struct cereal_Event eventd; cereal_read_Event(&eventd, eventp); double t = millis_since_boot(); - if (eventd.which == cereal_Event_live100) { - struct cereal_Live100Data datad; - cereal_read_Live100Data(&datad, eventd.live100); + if (eventd.which == cereal_Event_controlsState) { + struct cereal_ControlsState datad; + cereal_read_ControlsState(&datad, eventd.controlsState); if (datad.vCruise != s->scene.v_cruise) { s->scene.v_cruise_update_ts = eventd.logMonoTime; @@ -1888,19 +1889,19 @@ static void ui_update(UIState *s) { s->scene.alert_ts = eventd.logMonoTime; s->scene.alert_size = datad.alertSize; - if (datad.alertSize == cereal_Live100Data_AlertSize_none) { + if (datad.alertSize == cereal_ControlsState_AlertSize_none) { s->alert_size = ALERTSIZE_NONE; - } else if (datad.alertSize == cereal_Live100Data_AlertSize_small) { + } else if (datad.alertSize == cereal_ControlsState_AlertSize_small) { s->alert_size = ALERTSIZE_SMALL; - } else if (datad.alertSize == cereal_Live100Data_AlertSize_mid) { + } else if (datad.alertSize == cereal_ControlsState_AlertSize_mid) { s->alert_size = ALERTSIZE_MID; - } else if (datad.alertSize == cereal_Live100Data_AlertSize_full) { + } else if (datad.alertSize == cereal_ControlsState_AlertSize_full) { s->alert_size = ALERTSIZE_FULL; } - if (datad.alertStatus == cereal_Live100Data_AlertStatus_userPrompt) { + if (datad.alertStatus == cereal_ControlsState_AlertStatus_userPrompt) { update_status(s, STATUS_WARNING); - } else if (datad.alertStatus == cereal_Live100Data_AlertStatus_critical) { + } else if (datad.alertStatus == cereal_ControlsState_AlertStatus_critical) { update_status(s, STATUS_ALERT); } else if (datad.enabled) { update_status(s, STATUS_ENGAGED); @@ -1925,16 +1926,16 @@ static void ui_update(UIState *s) { } } } - } else if (eventd.which == cereal_Event_live20) { - struct cereal_Live20Data datad; - cereal_read_Live20Data(&datad, eventd.live20); - struct cereal_Live20Data_LeadData leaddatad; - cereal_read_Live20Data_LeadData(&leaddatad, datad.leadOne); + } else if (eventd.which == cereal_Event_radarState) { + struct cereal_RadarState datad; + cereal_read_RadarState(&datad, eventd.radarState); + struct cereal_RadarState_LeadData leaddatad; + cereal_read_RadarState_LeadData(&leaddatad, datad.leadOne); s->scene.lead_status = leaddatad.status; s->scene.lead_d_rel = leaddatad.dRel; s->scene.lead_y_rel = leaddatad.yRel; s->scene.lead_v_rel = leaddatad.vRel; - s->livempc_or_live20_changed = true; + s->livempc_or_radarstate_changed = true; } else if (eventd.which == cereal_Event_liveCalibration) { s->scene.world_objects_visible = true; struct cereal_LiveCalibrationData datad; @@ -1974,7 +1975,7 @@ static void ui_update(UIState *s) { for (int i = 0; i < 50; i++){ s->scene.mpc_y[i] = capn_to_f32(capn_get32(y_list, i)); } - s->livempc_or_live20_changed = true; + s->livempc_or_radarstate_changed = true; } else if (eventd.which == cereal_Event_thermal) { struct cereal_ThermalData datad; cereal_read_ThermalData(&datad, eventd.thermal); @@ -2056,6 +2057,7 @@ static int vision_subscribe(int fd, VisionPacket *rp, int type) { static void* vision_connect_thread(void *args) { int err; + set_thread_name("vision_connect"); UIState *s = args; while (!do_exit) { @@ -2093,6 +2095,7 @@ static void* vision_connect_thread(void *args) { static void* light_sensor_thread(void *args) { int err; + set_thread_name("light_sensor"); UIState *s = args; s->light_sensor = 0.0; @@ -2109,8 +2112,11 @@ static void* light_sensor_thread(void *args) { int SENSOR_LIGHT = 7; - device->activate(device, SENSOR_LIGHT, 0); - device->activate(device, SENSOR_LIGHT, 1); + err = device->activate(device, SENSOR_LIGHT, 0); + if (err != 0) goto fail; + err = device->activate(device, SENSOR_LIGHT, 1); + if (err != 0) goto fail; + device->setDelay(device, SENSOR_LIGHT, ms2ns(100)); while (!do_exit) { @@ -2127,11 +2133,17 @@ static void* light_sensor_thread(void *args) { } return NULL; + +fail: + LOGE("LIGHT SENSOR IS MISSING"); + s->light_sensor = 255; + return NULL; } static void* bg_thread(void* args) { UIState *s = args; + set_thread_name("bg"); EGLDisplay bg_display; EGLSurface bg_surface; @@ -2179,7 +2191,7 @@ int is_leon() { return strstr(str, "letv") != NULL; } -int main() { +int main(int argc, char* argv[]) { int err; setpriority(PRIO_PROCESS, 0, -14); @@ -2217,16 +2229,14 @@ int main() { } // light sensor scaling params - const int EON = (access("/EON", F_OK) != -1); const int LEON = is_leon(); const float BRIGHTNESS_B = LEON? 10.0 : 5.0; const float BRIGHTNESS_M = LEON? 2.6 : 1.3; - #define NEO_BRIGHTNESS 100 float smooth_brightness = BRIGHTNESS_B; - set_volume(s, 0); + set_volume(s, 13); #ifdef DEBUG_FPS vipc_t1 = millis_since_boot(); double t1 = millis_since_boot(); @@ -2241,17 +2251,11 @@ int main() { } pthread_mutex_lock(&s->lock); - if (EON) { - // light sensor is only exposed on EONs - - float clipped_brightness = (s->light_sensor*BRIGHTNESS_M) + BRIGHTNESS_B; - if (clipped_brightness > 255) clipped_brightness = 255; - smooth_brightness = clipped_brightness * 0.01 + smooth_brightness * 0.99; - set_brightness(s, (int)smooth_brightness); - } else { - // compromise for bright and dark envs - set_brightness(s, NEO_BRIGHTNESS); - } + // light sensor is only exposed on EONs + float clipped_brightness = (s->light_sensor*BRIGHTNESS_M) + BRIGHTNESS_B; + if (clipped_brightness > 255) clipped_brightness = 255; + smooth_brightness = clipped_brightness * 0.01 + smooth_brightness * 0.99; + set_brightness(s, (int)smooth_brightness); if (!s->vision_connected) { // Car is not started, keep in idle state and awake on touch events @@ -2309,23 +2313,10 @@ int main() { set_volume(s, volume); } - if (s->speed_lim_off_timeout > 0) { - s->speed_lim_off_timeout--; - } else { - read_speed_lim_off(s); - } - - if (s->is_metric_timeout > 0) { - s->is_metric_timeout--; - } else { - read_is_metric(s); - } - - if (s->limit_set_speed_timeout > 0) { - s->limit_set_speed_timeout--; - } else { - read_limit_set_speed(s); - } + read_param_bool_timeout(&s->is_metric, "IsMetric", &s->is_metric_timeout); + read_param_bool_timeout(&s->longitudinal_control, "LongitudinalControl", &s->longitudinal_control_timeout); + read_param_bool_timeout(&s->limit_set_speed, "LimitSetSpeed", &s->limit_set_speed_timeout); + read_param_float_timeout(&s->speed_lim_off, "SpeedLimitOffset", &s->limit_set_speed_timeout); pthread_mutex_unlock(&s->lock); diff --git a/selfdrive/version.py b/selfdrive/version.py index d1e263aec..4acc18350 100644 --- a/selfdrive/version.py +++ b/selfdrive/version.py @@ -2,24 +2,53 @@ import os import subprocess from selfdrive.swaglog import cloudlog + +def get_git_commit(): + return subprocess.check_output(["git", "rev-parse", "HEAD"]).strip() + + +def get_git_branch(): + return subprocess.check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"]).strip() + + +def get_git_full_branchname(): + return subprocess.check_output(["git", "rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{u}"]).strip() + + +def get_git_remote(): + try: + local_branch = subprocess.check_output(["git", "name-rev", "--name-only", "HEAD"]).strip() + tracking_remote = subprocess.check_output(["git", "config", "branch." + local_branch + ".remote"]).strip() + return subprocess.check_output(["git", "config", "remote." + tracking_remote + ".url"]).strip() + except subprocess.CalledProcessError: + # Not on a branch, fallback + return subprocess.check_output(["git", "config", "--get", "remote.origin.url"]).strip() + + with open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "common", "version.h")) as _versionf: version = _versionf.read().split('"')[1] try: - origin = subprocess.check_output(["git", "config", "--get", "remote.origin.url"]).rstrip() + origin = get_git_remote() if origin.startswith('git@github.com:commaai') or origin.startswith('https://github.com/commaai'): if origin.endswith('/one.git'): dirty = True else: - branch = subprocess.check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"]).rstrip() - branch = 'origin/' + branch - subprocess.check_call(["git", "update-index", "--refresh"]) #This is needed otherwise touched files might show up as modified + branch = get_git_full_branchname() + + # This is needed otherwise touched files might show up as modified + try: + subprocess.check_call(["git", "update-index", "--refresh"]) + except subprocess.CalledProcessError: + pass + dirty = subprocess.call(["git", "diff-index", "--quiet", branch, "--"]) != 0 if dirty: dirty_files = subprocess.check_output(["git", "diff-index", branch, "--"]) commit = subprocess.check_output(["git", "rev-parse", "--verify", "HEAD"]).rstrip() origin_commit = subprocess.check_output(["git", "rev-parse", "--verify", branch]).rstrip() cloudlog.event("dirty comma branch", vesion=version, dirty=dirty, origin=origin, branch=branch, dirty_files=dirty_files, commit=commit, origin_commit=origin_commit) + else: dirty = True except subprocess.CalledProcessError: @@ -29,5 +58,14 @@ except subprocess.CalledProcessError: pass dirty = True -# put this here training_version = "0.1.0" + +if __name__ == "__main__": + print("Dirty: %s" % dirty) + print("Version: %s" % version) + print("Remote: %s" % origin) + + try: + print("Branch %s" % branch) + except NameError: + pass diff --git a/selfdrive/visiond/camera_qcom.c b/selfdrive/visiond/camera_qcom.c index 45b782ecf..ccaee8575 100644 --- a/selfdrive/visiond/camera_qcom.c +++ b/selfdrive/visiond/camera_qcom.c @@ -292,10 +292,6 @@ void cameras_init(DualCameraState *s) { } else if (strcmp(product_name, "OnePlus3") == 0 && strcmp(project_name, "15811") == 0) { // only OP3T support s->device = DEVICE_OP3T; - } else if (strcmp(product_name, "LePro3") == 0) { - LOGD("LePro 3 detected"); - s->device = DEVICE_LP3; - assert(false); } else { assert(false); } @@ -423,7 +419,7 @@ static void set_exposure(CameraState *s, float exposure_frac, float gain_frac) { s->cur_gain_frac = gain_frac; } - LOGD("set exposure: %f %f - %d", exposure_frac, gain_frac, err); + //LOGD("set exposure: %f %f - %d", exposure_frac, gain_frac, err); } static void do_autoexposure(CameraState *s, float grey_frac) { @@ -431,7 +427,7 @@ static void do_autoexposure(CameraState *s, float grey_frac) { float new_exposure = s->cur_exposure_frac; new_exposure *= pow(1.05, (target_grey - grey_frac) / 0.05 ); - LOGD("diff %f: %f to %f", target_grey - grey_frac, s->cur_exposure_frac, new_exposure); + //LOGD("diff %f: %f to %f", target_grey - grey_frac, s->cur_exposure_frac, new_exposure); float new_gain = s->cur_gain_frac; if (new_exposure < 0.10) { @@ -1708,12 +1704,12 @@ void actuator_move(CameraState *s, uint16_t target) { .ringing_params = &actuator_ringing_params, }; err = ioctl(s->actuator_fd, VIDIOC_MSM_ACTUATOR_CFG, &actuator_cfg_data); - LOGD("actuator move focus: %d", err); + //LOGD("actuator move focus: %d", err); s->cur_step_pos = dest_step_pos; s->cur_lens_pos = actuator_cfg_data.cfg.move.curr_lens_pos; - LOGD("step %d target: %d lens pos: %d", dest_step_pos, target, s->cur_lens_pos); + //LOGD("step %d target: %d lens pos: %d", dest_step_pos, target, s->cur_lens_pos); } static void parse_autofocus(CameraState *s, uint8_t *d) { @@ -1778,12 +1774,12 @@ static void do_autofocus(CameraState *s) { int target = clamp(s->lens_true_pos - sag, dac_down, dac_up); - char debug[4096]; + /*char debug[4096]; char *pdebug = debug; pdebug += sprintf(pdebug, "focus "); for (int i = 0; i < NUM_FOCUS; i++) pdebug += sprintf(pdebug, "%2x(%4d) ", s->confidence[i], s->focus[i]); pdebug += sprintf(pdebug, " err: %7.2f offset: %6.2f sag: %6.2f lens_true_pos: %6.2f cur_lens_pos: %4d->%4d", err * focus_kp, offset, sag, s->lens_true_pos, s->cur_lens_pos, target); - LOGD(debug); + LOGD(debug);*/ actuator_move(s, target); } @@ -2109,7 +2105,7 @@ static void* ops_thread(void* arg) { if (zmq_msg_size(&msg) == sizeof(cmsg)) { memcpy(&cmsg, zmq_msg_data(&msg), zmq_msg_size(&msg)); - LOGD("cameraops %d", cmsg.type); + //LOGD("cameraops %d", cmsg.type); if (cmsg.type == CAMERA_MSG_AUTOEXPOSE) { if (cmsg.camera_num == 0) { diff --git a/selfdrive/visiond/visiond.cc b/selfdrive/visiond/visiond.cc index f7a52dc0e..77a7e5f48 100644 --- a/selfdrive/visiond/visiond.cc +++ b/selfdrive/visiond/visiond.cc @@ -781,7 +781,7 @@ void* monitoring_thread(void *arg) { double t2 = millis_since_boot(); - LOGD("monitoring process: %.2fms, from last %.2fms", t2-t1, t1-last); + //LOGD("monitoring process: %.2fms, from last %.2fms", t2-t1, t1-last); last = t1; } @@ -893,7 +893,7 @@ void* frontview_thread(void *arg) { double t2 = millis_since_boot(); - LOGD("front process: %.2fms", t2-t1); + //LOGD("front process: %.2fms", t2-t1); } return NULL; @@ -1157,7 +1157,7 @@ void* processing_thread(void *arg) { zmq_send(s->posenet_sock_raw, bytes.begin(), bytes.size(), ZMQ_DONTWAIT); } pt3 = millis_since_boot(); - LOGD("pre: %.2fms | posenet: %.2fms", (pt2-pt1), (pt3-pt1)); + //LOGD("pre: %.2fms | posenet: %.2fms", (pt2-pt1), (pt3-pt1)); } #endif @@ -1206,8 +1206,8 @@ void* processing_thread(void *arg) { double t5 = millis_since_boot(); - LOGD("queued: %.2fms, yuv: %.2f, model: %.2fms | processing: %.3fms", - (t2-t1), (yt2-yt1), (mt2-mt1), (t5-t1)); + /*LOGD("queued: %.2fms, yuv: %.2f, model: %.2fms | processing: %.3fms", + (t2-t1), (yt2-yt1), (mt2-mt1), (t5-t1));*/ } #ifdef DUMP_RGB