From 1efa3f0ebae15bad11ad33c910c9229c9b52be2c Mon Sep 17 00:00:00 2001 From: Drew Hintz Date: Thu, 4 Apr 2019 22:48:37 -0700 Subject: [PATCH 1/6] =?UTF-8?q?=F0=9F=93=8B=F0=9F=93=B7=202019=20Chrysler?= =?UTF-8?q?=20Pacifica=20and=202019=20Jeep=20Grand=20Cherokee=20support=20?= =?UTF-8?q?(#590)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 2019 Chrysler Pacfica and 2019 Jeep Grand Cherokee support, along with likely support for arbitrary models. This is done by copying most values from the stock LKAS camera which is active with https://github.com/commaai/panda/pull/177 * No longer send LKAS_HEARTBIT because Panda now forwards it for us. * Pacifica Hybrid 2018 combine fingerprints, add 808: 8 * panda chrysler: forward bus 0 to bus 2 copy of Panda commit: https://github.com/commaai/panda/commit/104950264473274e0012a39b7ea2d1468ef46d8d --- panda/board/safety/safety_chrysler.h | 23 ++++++++-- selfdrive/car/chrysler/carcontroller.py | 29 +++++++------ selfdrive/car/chrysler/carstate.py | 18 +++++++- selfdrive/car/chrysler/chryslercan.py | 38 +++++++---------- selfdrive/car/chrysler/chryslercan_test.py | 49 +++++++++++++++------- selfdrive/car/chrysler/interface.py | 16 ++++--- selfdrive/car/chrysler/values.py | 10 +++-- 7 files changed, 120 insertions(+), 63 deletions(-) diff --git a/panda/board/safety/safety_chrysler.h b/panda/board/safety/safety_chrysler.h index b1c6a743f..6cbf00385 100644 --- a/panda/board/safety/safety_chrysler.h +++ b/panda/board/safety/safety_chrysler.h @@ -5,7 +5,7 @@ const int CHRYSLER_MAX_RATE_UP = 3; const int CHRYSLER_MAX_RATE_DOWN = 3; const int CHRYSLER_MAX_TORQUE_ERROR = 80; // max torque cmd in excess of torque motor -int chrysler_camera_detected = 0; +int chrysler_camera_detected = 0; // is giraffe switch 2 high? int chrysler_rt_torque_last = 0; int chrysler_desired_torque_last = 0; int chrysler_cruise_engaged_last = 0; @@ -125,12 +125,29 @@ static int chrysler_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { return true; } +static void chrysler_init(int16_t param) { + chrysler_camera_detected = 0; +} + +static int chrysler_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { + int32_t addr = to_fwd->RIR >> 21; + // forward CAN 0 -> 2 so stock LKAS camera sees messages + if (bus_num == 0 && !chrysler_camera_detected) { + return 2; + } + // forward LKAS_HEARTBIT message from stock camera + if (bus_num == 2 && !chrysler_camera_detected && addr == 0x2d9) { + return 0; + } + return -1; // do not forward +} + const safety_hooks chrysler_hooks = { - .init = nooutput_init, + .init = chrysler_init, .rx = chrysler_rx_hook, .tx = chrysler_tx_hook, .tx_lin = nooutput_tx_lin_hook, .ignition = default_ign_hook, - .fwd = nooutput_fwd_hook, + .fwd = chrysler_fwd_hook, }; diff --git a/selfdrive/car/chrysler/carcontroller.py b/selfdrive/car/chrysler/carcontroller.py index 83c2ecc32..7db36634c 100644 --- a/selfdrive/car/chrysler/carcontroller.py +++ b/selfdrive/car/chrysler/carcontroller.py @@ -2,9 +2,9 @@ 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, create_lkas_heartbit, \ + create_wheel_buttons, \ create_chimes -from selfdrive.car.chrysler.values import ECU +from selfdrive.car.chrysler.values import ECU, CAR from selfdrive.can.packer import CANPacker AudibleAlert = car.CarControl.HUDControl.AudibleAlert @@ -29,6 +29,7 @@ class CarController(object): self.car_fingerprint = car_fingerprint self.alert_active = False self.send_chime = False + self.gone_fast_yet = False self.fake_ecus = set() if enable_camera: @@ -39,8 +40,8 @@ class CarController(object): def update(self, sendcan, 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 @@ -51,6 +52,11 @@ class CarController(object): CS.steer_torque_motor, SteerLimitParams) moving_fast = CS.v_ego > CS.CP.minSteerSpeed # for status message + if CS.v_ego > (CS.CP.minSteerSpeed - 0.5): # for command high bit + self.gone_fast_yet = True + elif self.car_fingerprint in (CAR.PACIFICA_2019_HYBRID, CAR.JEEP_CHEROKEE_2019): + if CS.v_ego < (CS.CP.minSteerSpeed - 3.0): + self.gone_fast_yet = False # < 14.5m/s stock turns off this bit, but fine down to 13.5 lkas_active = moving_fast and enabled if not lkas_active: @@ -76,18 +82,17 @@ class CarController(object): new_msg = create_wheel_buttons(self.ccframe) can_sends.append(new_msg) + # LKAS_HEARTBIT is forwarded by Panda so no need to send it here. # frame is 100Hz (0.01s period) - if (self.ccframe % 10 == 0): # 0.1s period - new_msg = create_lkas_heartbit(self.car_fingerprint) - can_sends.append(new_msg) - if (self.ccframe % 25 == 0): # 0.25s period - new_msg = create_lkas_hud(self.packer, CS.gear_shifter, lkas_active, hud_alert, self.car_fingerprint, - self.hud_count) - can_sends.append(new_msg) - self.hud_count += 1 + if (CS.lkas_car_model != -1): + new_msg = create_lkas_hud( + self.packer, CS.gear_shifter, lkas_active, hud_alert, + self.hud_count, CS.lkas_car_model) + can_sends.append(new_msg) + self.hud_count += 1 - new_msg = create_lkas_command(self.packer, int(apply_steer), frame) + new_msg = create_lkas_command(self.packer, int(apply_steer), self.gone_fast_yet, frame) can_sends.append(new_msg) self.ccframe += 1 diff --git a/selfdrive/car/chrysler/carstate.py b/selfdrive/car/chrysler/carstate.py index a6344027d..fd3c081f3 100644 --- a/selfdrive/car/chrysler/carstate.py +++ b/selfdrive/car/chrysler/carstate.py @@ -63,6 +63,18 @@ def get_can_parser(CP): return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 0) +def get_camera_parser(CP): + signals = [ + # sig_name, sig_address, default + # TODO read in all the other values + ("COUNTER", "LKAS_COMMAND", -1), + ("CAR_MODEL", "LKAS_HUD", -1), + ("LKAS_STATUS_OK", "LKAS_HEARTBIT", -1) + ] + checks = [] + + return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 2) + class CarState(object): def __init__(self, CP): @@ -85,7 +97,7 @@ class CarState(object): self.v_ego = 0.0 - def update(self, cp): + def update(self, cp, cp_cam): # copy can_valid self.can_valid = cp.can_valid @@ -142,3 +154,7 @@ class CarState(object): self.pcm_acc_status = self.main_on self.generic_toggle = bool(cp.vl["STEERING_LEVERS"]['HIGH_BEAM_FLASH']) + + self.lkas_counter = cp_cam.vl["LKAS_COMMAND"]['COUNTER'] + self.lkas_car_model = cp_cam.vl["LKAS_HUD"]['CAR_MODEL'] + self.lkas_status_ok = cp_cam.vl["LKAS_HEARTBIT"]['LKAS_STATUS_OK'] diff --git a/selfdrive/car/chrysler/chryslercan.py b/selfdrive/car/chrysler/chryslercan.py index e17ee3623..53c1eb662 100644 --- a/selfdrive/car/chrysler/chryslercan.py +++ b/selfdrive/car/chrysler/chryslercan.py @@ -5,14 +5,6 @@ from selfdrive.car.chrysler.values import CAR VisualAlert = car.CarControl.HUDControl.VisualAlert AudibleAlert = car.CarControl.HUDControl.AudibleAlert -MODEL_TO_CONSTANT = { - CAR.PACIFICA_2017_HYBRID: 0, - CAR.PACIFICA_2018: 0x64, - CAR.PACIFICA_2018_HYBRID: 0xa8, - CAR.PACIFICA_2019_HYBRID: 0x68, - CAR.JEEP_CHEROKEE: 0xa4, - } - def calc_checksum(data): """This function does not want the checksum byte in the input data. @@ -53,28 +45,26 @@ def calc_checksum(data): def make_can_msg(addr, dat): return [addr, 0, dat, 0] -def create_lkas_heartbit(car_fingerprint): - # LKAS_HEARTBIT (729) Lane-keeping heartbeat. - msg = '0000000820'.decode('hex') # 2017 - return make_can_msg(0x2d9, msg) +def create_lkas_heartbit(packer, lkas_status_ok): + # LKAS_HEARTBIT 0x2d9 (729) Lane-keeping heartbeat. + values = { + "LKAS_STATUS_OK": lkas_status_ok + } + return packer.make_can_msg("LKAS_HEARTBIT", 0, values) -def create_lkas_hud(packer, gear, lkas_active, hud_alert, car_fingerprint, hud_count): +def create_lkas_hud(packer, gear, lkas_active, hud_alert, hud_count, lkas_car_model): # LKAS_HUD 0x2a6 (678) Controls what lane-keeping icon is displayed. if hud_alert == VisualAlert.steerRequired: msg = '0000000300000000'.decode('hex') return make_can_msg(0x2a6, msg) - color = 0 # default values are for park or neutral - lines = 0 + color = 1 # default values are for park or neutral in 2017 are 0 0, but trying 1 1 for 2019 + lines = 1 alerts = 0 - if hud_count < (3 *4): # first 3 seconds, 4Hz - lines = 1 + if hud_count < (1 *4): # first 3 seconds, 4Hz alerts = 1 - elif hud_count < (6 * 4): # next 3 seconds, 4Hz - lines = 1 - alerts = 0 # CAR.PACIFICA_2018_HYBRID and CAR.PACIFICA_2019_HYBRID # had color = 1 and lines = 1 but trying 2017 hybrid style for now. if gear in ('drive', 'reverse', 'low'): @@ -87,7 +77,7 @@ def create_lkas_hud(packer, gear, lkas_active, hud_alert, car_fingerprint, hud_c values = { "LKAS_ICON_COLOR": color, # byte 0, last 2 bits - "CAR_MODEL": MODEL_TO_CONSTANT[car_fingerprint], # byte 1 + "CAR_MODEL": lkas_car_model, # byte 1 "LKAS_LANE_LINES": lines, # byte 2, last 4 bits "LKAS_ALERTS": alerts, # byte 3, last 4 bits } @@ -95,11 +85,11 @@ def create_lkas_hud(packer, gear, lkas_active, hud_alert, car_fingerprint, hud_c return packer.make_can_msg("LKAS_HUD", 0, values) # 0x2a6 -def create_lkas_command(packer, apply_steer, frame): - # LKAS_COMMAND (658) Lane-keeping signal to turn the wheel. +def create_lkas_command(packer, apply_steer, moving_fast, frame): + # LKAS_COMMAND 0x292 (658) Lane-keeping signal to turn the wheel. values = { "LKAS_STEERING_TORQUE": apply_steer, - "LKAS_HIGH_TORQUE": 1, + "LKAS_HIGH_TORQUE": int(moving_fast), "COUNTER": frame % 0x10, } diff --git a/selfdrive/car/chrysler/chryslercan_test.py b/selfdrive/car/chrysler/chryslercan_test.py index 2edfff9f2..b4ca4a91f 100644 --- a/selfdrive/car/chrysler/chryslercan_test.py +++ b/selfdrive/car/chrysler/chryslercan_test.py @@ -1,5 +1,6 @@ import chryslercan from values import CAR +from carcontroller import CarController from selfdrive.can.packer import CANPacker from cereal import car @@ -16,32 +17,52 @@ class TestChryslerCan(unittest.TestCase): self.assertEqual(0xcc, chryslercan.calc_checksum([0x14, 0, 0, 0, 0x20])) def test_heartbit(self): + packer = CANPacker('chrysler_pacifica_2017_hybrid') self.assertEqual( [0x2d9, 0, '0000000820'.decode('hex'), 0], - chryslercan.create_lkas_heartbit(CAR.PACIFICA_2017_HYBRID)) + chryslercan.create_lkas_heartbit(packer, 0x820)) def test_hud(self): packer = CANPacker('chrysler_pacifica_2017_hybrid') self.assertEqual( - [0x2a6, 0, '0000010100000000'.decode('hex'), 0], - chryslercan.create_lkas_hud(packer, - 'park', False, False, CAR.PACIFICA_2017_HYBRID, 1)) + [0x2a6, 0, '0100010100000000'.decode('hex'), 0], + chryslercan.create_lkas_hud( + packer, + 'park', False, False, 1, 0)) self.assertEqual( - [0x2a6, 0, '0000010000000000'.decode('hex'), 0], - chryslercan.create_lkas_hud(packer, - 'park', False, False, CAR.PACIFICA_2017_HYBRID, 5*4)) + [0x2a6, 0, '0100010000000000'.decode('hex'), 0], + chryslercan.create_lkas_hud( + packer, + 'park', False, False, 5*4, 0)) self.assertEqual( - [0x2a6, 0, '0000000000000000'.decode('hex'), 0], - chryslercan.create_lkas_hud(packer, - 'park', False, False, CAR.PACIFICA_2017_HYBRID, 99999)) + [0x2a6, 0, '0100010000000000'.decode('hex'), 0], + chryslercan.create_lkas_hud( + packer, + 'park', False, False, 99999, 0)) self.assertEqual( [0x2a6, 0, '0200060000000000'.decode('hex'), 0], - chryslercan.create_lkas_hud(packer, - 'drive', True, False, CAR.PACIFICA_2017_HYBRID, 99999)) + chryslercan.create_lkas_hud( + packer, + 'drive', True, False, 99999, 0)) self.assertEqual( [0x2a6, 0, '0264060000000000'.decode('hex'), 0], - chryslercan.create_lkas_hud(packer, - 'drive', True, False, CAR.PACIFICA_2018, 99999)) + chryslercan.create_lkas_hud( + packer, + 'drive', True, False, 99999, 0x64)) + + def test_command(self): + packer = CANPacker('chrysler_pacifica_2017_hybrid') + self.assertEqual( + [0x292, 0, '140000001086'.decode('hex'), 0], + chryslercan.create_lkas_command( + packer, + 0, True, 1)) + self.assertEqual( + [0x292, 0, '040000008083'.decode('hex'), 0], + chryslercan.create_lkas_command( + packer, + 0, False, 8)) + if __name__ == '__main__': unittest.main() diff --git a/selfdrive/car/chrysler/interface.py b/selfdrive/car/chrysler/interface.py index ac797616b..7e96ebc2b 100755 --- a/selfdrive/car/chrysler/interface.py +++ b/selfdrive/car/chrysler/interface.py @@ -4,7 +4,7 @@ from cereal import car from selfdrive.config import Conversions as CV from selfdrive.controls.lib.drive_helpers import EventTypes as ET, create_event from selfdrive.controls.lib.vehicle_model import VehicleModel -from selfdrive.car.chrysler.carstate import CarState, get_can_parser +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: @@ -27,8 +27,8 @@ class CarInterface(object): # *** init the major players *** self.CS = CarState(CP) - self.cp = get_can_parser(CP) + self.cp_cam = get_camera_parser(CP) # sending if read only is False if sendcan is not None: @@ -79,7 +79,7 @@ class CarInterface(object): ret.steerActuatorDelay = 0.1 ret.steerRateCost = 0.7 - if candidate == CAR.JEEP_CHEROKEE: + if candidate in (CAR.JEEP_CHEROKEE, CAR.JEEP_CHEROKEE_2019): ret.wheelbase = 2.91 # in meters ret.steerRatio = 12.7 ret.steerActuatorDelay = 0.2 # in seconds @@ -91,6 +91,9 @@ class CarInterface(object): ret.minSteerSpeed = 3.8 # m/s ret.minEnableSpeed = -1. # enable is done by stock ACC, so ignore this + if candidate in (CAR.PACIFICA_2019_HYBRID, CAR.JEEP_CHEROKEE_2019): + ret.minSteerSpeed = 17.5 # m/s 17 on the way up, 13 on the way down once engaged. + # TODO allow 2019 cars to steer down to 13 m/s if already engaged. centerToRear = ret.wheelbase - ret.centerToFront # TODO: get actual value, for now starting with reasonable value for @@ -137,10 +140,9 @@ class CarInterface(object): def update(self, c): # ******************* do can recv ******************* canMonoTimes = [] - self.cp.update(int(sec_since_boot() * 1e9), False) - - self.CS.update(self.cp) + self.cp_cam.update(int(sec_since_boot() * 1e9), False) + self.CS.update(self.cp, self.cp_cam) # create message ret = car.CarState.new_message() @@ -208,6 +210,8 @@ class CarInterface(object): self.low_speed_alert = (ret.vEgo < self.CP.minSteerSpeed) ret.genericToggle = self.CS.generic_toggle + #ret.lkasCounter = self.CS.lkas_counter + #ret.lkasCarModel = self.CS.lkas_car_model # events events = [] diff --git a/selfdrive/car/chrysler/values.py b/selfdrive/car/chrysler/values.py index 6e3a24b8f..4636b89a3 100644 --- a/selfdrive/car/chrysler/values.py +++ b/selfdrive/car/chrysler/values.py @@ -6,6 +6,7 @@ class CAR: PACIFICA_2019_HYBRID = "CHRYSLER PACIFICA HYBRID 2019" PACIFICA_2018 = "CHRYSLER PACIFICA 2018" JEEP_CHEROKEE = "JEEP GRAND CHEROKEE V6 2018" # Also covers Tailhawk 2017. + JEEP_CHEROKEE_2019 = "JEEP GRAND CHEROKEE 2019" # Unique can messages: # Only the hybrids have 270: 8 @@ -24,11 +25,9 @@ FINGERPRINTS = { ], CAR.PACIFICA_2018: [ {55: 8, 257: 5, 258: 8, 264: 8, 268: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 292: 8, 294: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 368: 8, 376: 3, 384: 8, 388: 4, 416: 7, 448: 6, 456: 4, 464: 8, 469: 8, 480: 8, 500: 8, 501: 8, 512: 8, 514: 8, 520: 8, 528: 8, 532: 8, 544: 8, 557: 8, 559: 8, 560: 4, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 658: 6, 660: 8, 669: 3, 671: 8, 672: 8, 678: 8, 680: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 729: 5, 736: 8, 746: 5, 752: 2, 760: 8, 764: 8, 766: 8, 770: 8, 773: 8, 779: 8, 784: 8, 792: 8, 799: 8, 800: 8, 804: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 832: 8, 838: 2, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 882: 8, 897: 8, 924: 8, 926: 3, 937: 8, 947: 8, 948: 8, 969: 4, 974: 5, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1098: 8, 1100: 8}, - ], CAR.PACIFICA_2018_HYBRID: [ - {68: 8, 257: 5, 258: 8, 264: 8, 268: 8, 270: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 291: 8, 292: 8, 294: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 368: 8, 376: 3, 384: 8, 388: 4, 448: 6, 456: 4, 464: 8, 469: 8, 480: 8, 500: 8, 501: 8, 512: 8, 514: 8, 520: 8, 528: 8, 532: 8, 544: 8, 557: 8, 559: 8, 560: 4, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 653: 8, 654: 8, 655: 8, 660: 8, 669: 3, 671: 8, 672: 8, 680: 8, 701: 8, 704: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 736: 8, 737: 8, 746: 5, 760: 8, 764: 8, 766: 8, 770: 8, 773: 8, 779: 8, 782: 8, 784: 8, 792: 8, 799: 8, 800: 8, 804: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 832: 8, 838: 2, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 878: 8, 882: 8, 897: 8, 908: 8, 924: 8, 926: 3, 929: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 958: 8, 959: 8, 969: 4, 974: 5, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1082: 8, 1083: 8, 1098: 8, 1100: 8}, - {168: 8, 257: 5, 258: 8, 264: 8, 268: 8, 270: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 291: 8, 292: 8, 294: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 368: 8, 376: 3, 384: 8, 388: 4, 448: 6, 456: 4, 464: 8, 469: 8, 480: 8, 500: 8, 501: 8, 512: 8, 514: 8, 520: 8, 528: 8, 532: 8, 544: 8, 557: 8, 559: 8, 560: 4, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 653: 8, 654: 8, 655: 8, 660: 8, 669: 3, 671: 8, 672: 8, 680: 8, 701: 8, 704: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 736: 8, 737: 8, 746: 5, 760: 8, 764: 8, 766: 8, 770: 8, 773: 8, 779: 8, 782: 8, 784: 8, 792: 8, 799: 8, 800: 8, 804: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 832: 8, 838: 2, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 878: 8, 882: 8, 897: 8, 908: 8, 924: 8, 926: 3, 929: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 958: 8, 959: 8, 969: 4, 974: 5, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1082: 8, 1083: 8, 1098: 8, 1100: 8}, + {68: 8, 168: 8, 257: 5, 258: 8, 264: 8, 268: 8, 270: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 291: 8, 292: 8, 294: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 368: 8, 376: 3, 384: 8, 388: 4, 448: 6, 456: 4, 464: 8, 469: 8, 480: 8, 500: 8, 501: 8, 512: 8, 514: 8, 520: 8, 528: 8, 532: 8, 544: 8, 557: 8, 559: 8, 560: 4, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 653: 8, 654: 8, 655: 8, 660: 8, 669: 3, 671: 8, 672: 8, 680: 8, 701: 8, 704: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 736: 8, 737: 8, 746: 5, 760: 8, 764: 8, 766: 8, 770: 8, 773: 8, 779: 8, 782: 8, 784: 8, 792: 8, 799: 8, 800: 8, 804: 8, 808: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 832: 8, 838: 2, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 878: 8, 882: 8, 897: 8, 908: 8, 924: 8, 926: 3, 929: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 958: 8, 959: 8, 969: 4, 974: 5, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1082: 8, 1083: 8, 1098: 8, 1100: 8}, ], CAR.PACIFICA_2019_HYBRID: [ {168: 8, 257: 5, 258: 8, 264: 8, 268: 8, 270: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 291: 8, 292: 8, 294: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 368: 8, 376: 3, 384: 8, 388: 4, 448: 6, 456: 4, 464: 8, 469: 8, 480: 8, 500: 8, 501: 8, 512: 8, 514: 8, 515: 7, 516: 7, 517: 7, 518: 7, 520: 8, 528: 8, 532: 8, 542: 8, 544: 8, 557: 8, 559: 8, 560: 8, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 653: 8, 654: 8, 655: 8, 660: 8, 669: 3, 671: 8, 672: 8, 680: 8, 701: 8, 703: 8, 704: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 736: 8, 737: 8, 746: 5, 752: 2, 754: 8, 760: 8, 764: 8, 766: 8, 770:8, 773: 8, 779: 8, 782: 8, 784: 8, 792: 8, 799: 8, 800: 8, 804: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 832: 8, 838: 2, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 878: 8, 882: 8, 897: 8, 906: 8, 908: 8, 924: 8, 926: 3, 929: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 958: 8, 959: 8, 962: 8, 969: 4, 973: 8, 974: 5, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1082: 8, 1083: 8, 1098: 8, 1100: 8, 1538: 8}, @@ -42,6 +41,8 @@ FINGERPRINTS = { {55: 8, 168: 8, 181: 8, 256: 4, 257: 5, 258: 8, 264: 8, 268: 8, 272: 6, 273: 6, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 292: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 352: 8, 362: 8, 368: 8, 376: 3, 384: 8, 388: 4, 416: 7, 448: 6, 456: 4, 464: 8, 500: 8, 501: 8, 512: 8, 514: 8, 520: 8, 532: 8, 544: 8, 557: 8, 559: 8, 560: 4, 564: 4, 571: 3, 579: 8, 584: 8, 608: 8, 624: 8, 625: 8, 632: 8, 639: 8, 656: 4, 658: 6, 660: 8, 671: 8, 672: 8, 676: 8, 678: 8, 680: 8, 683: 8, 684: 8, 703: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 729: 5, 736: 8, 737: 8, 738: 8, 746: 5, 752: 2, 754: 8, 760: 8, 761: 8, 764: 8, 766: 8, 773: 8, 776: 8, 779: 8, 782: 8, 783: 8, 784: 8, 785: 8, 788: 3, 792: 8, 799: 8, 800: 8, 804: 8, 806: 2, 808: 8, 810: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 831: 6, 832: 8, 838: 2, 844: 5, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 882: 8, 897: 8, 906: 8, 924: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 968: 8, 969: 4, 970: 8, 973: 8, 974: 5, 976: 8, 977: 4, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1062: 8, 1098: 8, 1100: 8}, # Jeep Grand Cherokee 2017 Trailhawk {257: 5, 258: 8, 264: 8, 268: 8, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 292: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 352: 8, 362: 8, 368: 8, 376: 3, 384: 8, 388: 4, 416: 7, 448: 6, 456: 4, 464: 8, 500: 8, 501: 8, 512: 8, 514: 8, 520: 8, 532: 8, 544: 8, 557: 8, 559: 8, 560: 4, 564: 4, 571: 3, 584: 8, 608: 8, 618: 8, 624: 8, 625: 8, 632: 8, 639: 8, 660: 8, 671: 8, 672: 8, 680: 8, 684: 8, 703: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 736: 8, 737: 8, 746: 5, 752: 2, 760: 8, 761: 8, 764: 8, 766: 8, 773: 8, 776: 8, 779: 8, 783: 8, 784: 8, 792: 8, 799: 8, 800: 8, 804: 8, 806: 2, 808: 8, 810: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 831: 6, 832: 8, 838: 2, 844: 5, 848: 8, 853: 8, 856: 4, 860: 6, 863: 8, 882: 8, 897: 8, 924: 3, 937: 8, 947: 8, 948: 8, 969: 4, 974: 5, 977: 4, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1062: 8, 1098: 8, 1100: 8}, + ], + CAR.JEEP_CHEROKEE_2019: [ # Jeep Grand Cherokee 2019 from Switzerland # 530: 8 is so far only in this Jeep. {55: 8, 181: 8, 256: 4, 257: 5, 258: 8, 264: 8, 268: 8, 272: 6, 273: 6, 274: 2, 280: 8, 284: 8, 288: 7, 290: 6, 292: 8, 300: 8, 308: 8, 320: 8, 324: 8, 331: 8, 332: 8, 344: 8, 352: 8, 362: 8, 368: 8, 376: 3, 384: 8, 388: 4, 416: 7, 448: 6, 456: 4, 464: 8, 500: 8, 501: 8, 512: 8, 514: 8, 520: 8, 530: 8, 532: 8, 544: 8, 557: 8, 559: 8, 560: 8, 564: 8, 571: 3, 579: 8, 584: 8, 608: 8, 618: 8, 624: 8, 625: 8, 632: 8, 639: 8, 660: 8, 671: 8, 672: 8, 676: 8, 680: 8, 683: 8, 684: 8, 703: 8, 705: 8, 706: 8, 709: 8, 710: 8, 719: 8, 720: 6, 736: 8, 737: 8, 738: 8, 746: 5, 752: 2, 754: 8, 760: 8, 761: 8, 764: 8, 773: 8, 776: 8, 779: 8, 782: 8, 783: 8, 784: 8, 792: 8, 799: 8, 804: 8, 806: 2, 808: 8, 816: 8, 817: 8, 820: 8, 825: 2, 826: 8, 831: 6, 832: 8, 838: 2, 844: 5, 848: 8, 853: 8, 856: 4, 860: 6, 882: 8, 897: 8, 906: 8, 924: 8, 937: 8, 938: 8, 939: 8, 940: 8, 941: 8, 942: 8, 943: 8, 947: 8, 948: 8, 968: 8, 969: 4, 970: 8, 973: 8, 974: 5, 977: 4, 979: 8, 980: 8, 981: 8, 982: 8, 983: 8, 984: 8, 992: 8, 993: 7, 995: 8, 996: 8, 1000: 8, 1001: 8, 1002: 8, 1003: 8, 1008: 8, 1009: 8, 1010: 8, 1011: 8, 1012: 8, 1013: 8, 1014: 8, 1015: 8, 1024: 8, 1025: 8, 1026: 8, 1031: 8, 1033: 8, 1050: 8, 1059: 8, 1062: 8, 1098: 8, 1100: 8}, @@ -65,6 +66,9 @@ DBC = { CAR.JEEP_CHEROKEE: dbc_dict( # Same DBC file works. 'chrysler_pacifica_2017_hybrid', # 'pt' 'chrysler_pacifica_2017_hybrid_private_fusion'), # 'radar' + CAR.JEEP_CHEROKEE_2019: dbc_dict( # Same DBC file works. + 'chrysler_pacifica_2017_hybrid', # 'pt' + 'chrysler_pacifica_2017_hybrid_private_fusion'), # 'radar' } STEER_THRESHOLD = 120 From dd323433421857af6791bcc0bd4a25f53ec14936 Mon Sep 17 00:00:00 2001 From: Drew Hintz Date: Thu, 4 Apr 2019 23:45:57 -0700 Subject: [PATCH 2/6] Add Chrysler Pacifica Hybrid 2019 (#591) Add Chrysler Pacifica Hybrid 2019 to list of supported cars. Clarify Jeep 2019 minimum steering speed. --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f8052b285..f63d6bcd7 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,7 @@ Supported Cars | Cadillac3 | ATS 2018 | Adaptive Cruise | Yes | Yes | 0mph | 7mph | Custom7| | Chrysler | Pacifica 2018 | Adaptive Cruise | Yes | Stock | 0mph | 9mph | FCA | | Chrysler | Pacifica Hybrid 2017-18 | Adaptive Cruise | Yes | Stock | 0mph | 9mph | FCA | +| Chrysler | Pacifica Hybrid 2019 | Adaptive Cruise | Yes | Stock | 0mph | 39mph | FCA | | GMC3 | Acadia Denali 2018 | Adaptive Cruise | Yes | Yes | 0mph | 7mph | Custom7| | Holden3 | Astra 2017 | Adaptive Cruise | Yes | Yes | 0mph | 7mph | Custom7| | Honda | Accord 2018 | All | Yes | Stock | 0mph | 3mph | Bosch | @@ -83,7 +84,8 @@ Supported Cars | Hyundai | Santa Fe 2019 | All | Yes | Stock | 0mph | 0mph | Custom6| | Hyundai | Elantra 2017 | SCC + LKAS | Yes | Stock | 19mph | 34mph | Custom6| | Hyundai | Genesis 2018 | All | Yes | Stock | 19mph | 34mph | Custom6| -| Jeep | Grand Cherokee 2017-19 | Adaptive Cruise | Yes | Stock | 0mph | 9mph | FCA | +| Jeep | Grand Cherokee 2017-18 | Adaptive Cruise | Yes | Stock | 0mph | 9mph | FCA | +| Jeep | Grand Cherokee 2019 | Adaptive Cruise | Yes | Stock | 0mph | 39mph | FCA | | Kia | Optima 2019 | SCC + LKAS | Yes | Stock | 0mph | 0mph | Custom6| | Kia | Sorento 2018 | All | Yes | Stock | 0mph | 0mph | Custom6| | Kia | Stinger 2018 | SCC + LKAS | Yes | Stock | 0mph | 0mph | Custom6| From 4662cfc8d72a805f789a4a35df51a9fa2cee8b99 Mon Sep 17 00:00:00 2001 From: Riccardo Date: Fri, 5 Apr 2019 00:27:39 -0700 Subject: [PATCH 3/6] Chrysler: matching file in panda repo --- panda/board/safety/safety_chrysler.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/panda/board/safety/safety_chrysler.h b/panda/board/safety/safety_chrysler.h index 6cbf00385..4af588401 100644 --- a/panda/board/safety/safety_chrysler.h +++ b/panda/board/safety/safety_chrysler.h @@ -135,8 +135,8 @@ static int chrysler_fwd_hook(int bus_num, CAN_FIFOMailBox_TypeDef *to_fwd) { if (bus_num == 0 && !chrysler_camera_detected) { return 2; } - // forward LKAS_HEARTBIT message from stock camera - if (bus_num == 2 && !chrysler_camera_detected && addr == 0x2d9) { + // forward all messages from camera except LKAS_COMMAND and LKAS_HUD + if (bus_num == 2 && !chrysler_camera_detected && addr != 658 && addr != 678) { return 0; } return -1; // do not forward From bdf65856506414ed57afe8b79a345ae2477632f4 Mon Sep 17 00:00:00 2001 From: dekerr Date: Sat, 6 Apr 2019 01:59:38 -0400 Subject: [PATCH 4/6] remove transpose (#588) --- common/transformations/camera.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/transformations/camera.py b/common/transformations/camera.py index 42432a7bb..367c0879a 100644 --- a/common/transformations/camera.py +++ b/common/transformations/camera.py @@ -64,7 +64,7 @@ def normalize(img_pts, intrinsics=eon_intrinsics): input_shape = img_pts.shape img_pts = np.atleast_2d(img_pts) img_pts = np.hstack((img_pts, np.ones((img_pts.shape[0],1)))) - img_pts_normalized = intrinsics_inv.dot(img_pts.T).T + img_pts_normalized = img_pts.dot(intrinsics_inv.T) img_pts_normalized[(img_pts < 0).any(axis=1)] = np.nan return img_pts_normalized[:,:2].reshape(input_shape) @@ -76,7 +76,7 @@ def denormalize(img_pts, intrinsics=eon_intrinsics): input_shape = img_pts.shape img_pts = np.atleast_2d(img_pts) img_pts = np.hstack((img_pts, np.ones((img_pts.shape[0],1)))) - img_pts_denormalized = intrinsics.dot(img_pts.T).T + img_pts_denormalized = img_pts.dot(intrinsics.T) img_pts_denormalized[img_pts_denormalized[:,0] > W] = np.nan img_pts_denormalized[img_pts_denormalized[:,0] < 0] = np.nan img_pts_denormalized[img_pts_denormalized[:,1] > H] = np.nan From e89fd1236f5207053e18718e9e8e6bf95365841a Mon Sep 17 00:00:00 2001 From: eFini Date: Tue, 9 Apr 2019 10:58:56 +1000 Subject: [PATCH 5/6] Add Port for 2019 Honda Odyssey Exclusive (China version) (#592) * Port for 2019 Honda Odyssey China ver * update as per comments --- selfdrive/car/honda/carcontroller.py | 2 ++ selfdrive/car/honda/carstate.py | 39 +++++++++++++++++++++++----- selfdrive/car/honda/hondacan.py | 4 +-- selfdrive/car/honda/interface.py | 13 ++++++++++ selfdrive/car/honda/values.py | 7 +++++ 5 files changed, 56 insertions(+), 9 deletions(-) diff --git a/selfdrive/car/honda/carcontroller.py b/selfdrive/car/honda/carcontroller.py index 08c0235fd..9325e8964 100644 --- a/selfdrive/car/honda/carcontroller.py +++ b/selfdrive/car/honda/carcontroller.py @@ -138,6 +138,8 @@ class CarController(object): STEER_MAX = 0xF00 elif CS.CP.carFingerprint in (CAR.CRV, CAR.ACURA_RDX): STEER_MAX = 0x3e8 # CR-V only uses 12-bits and requires a lower value (max value from energee) + elif CS.CP.carFingerprint in (CAR.ODYSSEY_CHN): + STEER_MAX = 0x7FFF else: STEER_MAX = 0x1000 diff --git a/selfdrive/car/honda/carstate.py b/selfdrive/car/honda/carstate.py index 718e7ae61..c3ef71b5e 100644 --- a/selfdrive/car/honda/carstate.py +++ b/selfdrive/car/honda/carstate.py @@ -60,15 +60,24 @@ def get_can_signals(CP): ("ENGINE_DATA", 100), ("WHEEL_SPEEDS", 50), ("STEERING_SENSORS", 100), - ("SCM_FEEDBACK", 10), ("GEARBOX", 100), ("SEATBELT_STATUS", 10), ("CRUISE", 10), ("POWERTRAIN_DATA", 100), ("VSA_STATUS", 50), - ("SCM_BUTTONS", 25), ] + if CP.carFingerprint == CAR.ODYSSEY_CHN: + checks += [ + ("SCM_FEEDBACK", 25), + ("SCM_BUTTONS", 50), + ] + else: + checks += [ + ("SCM_FEEDBACK", 10), + ("SCM_BUTTONS", 25), + ] + if CP.radarOffCan: # Civic is only bosch to use the same brake message as other hondas. if CP.carFingerprint not in (CAR.ACCORDH, CAR.CIVIC_BOSCH): @@ -85,11 +94,17 @@ def get_can_signals(CP): ("BRAKE_ERROR_2", "STANDSTILL", 1), ("CRUISE_SPEED_PCM", "CRUISE", 0), ("CRUISE_SPEED_OFFSET", "CRUISE_PARAMS", 0)] - checks += [("CRUISE_PARAMS", 50), - ("STANDSTILL", 50)] + checks += [("STANDSTILL", 50)] + + if CP.carFingerprint == CAR.ODYSSEY_CHN: + checks += [("CRUISE_PARAMS", 10)] + else: + checks += [("CRUISE_PARAMS", 50)] if CP.carFingerprint in (CAR.ACCORD, CAR.ACCORD_15, CAR.ACCORDH, CAR.CIVIC_BOSCH): signals += [("DRIVERS_DOOR_OPEN", "SCM_FEEDBACK", 1)] + elif CP.carFingerprint == CAR.ODYSSEY_CHN: + signals += [("DRIVERS_DOOR_OPEN", "SCM_BUTTONS", 1)] else: signals += [("DOOR_OPEN_FL", "DOORS_STATUS", 1), ("DOOR_OPEN_FR", "DOORS_STATUS", 1), @@ -114,6 +129,10 @@ def get_can_signals(CP): elif CP.carFingerprint == CAR.PILOT: signals += [("MAIN_ON", "SCM_BUTTONS", 0), ("CAR_GAS", "GAS_PEDAL_2", 0)] + elif CP.carFingerprint == CAR.ODYSSEY_CHN: + signals += [("MAIN_ON", "SCM_BUTTONS", 0), + ("EPB_STATE", "EPB_STATUS", 0)] + checks += [("EPB_STATUS", 50)] # add gas interceptor reading if we are using it if CP.enableGasInterceptor: @@ -130,9 +149,9 @@ def get_can_parser(CP): def get_cam_can_parser(CP): signals = [] - # all hondas except CRV and RDX use 0xe4 for steering + # all hondas except CRV, RDX and 2019 Odyssey@China use 0xe4 for steering checks = [(0xe4, 100)] - if CP.carFingerprint in [CAR.CRV, CAR.ACURA_RDX]: + if CP.carFingerprint in [CAR.CRV, CAR.ACURA_RDX, CAR.ODYSSEY_CHN]: checks = [(0x194, 100)] cam_bus = 1 if CP.carFingerprint in HONDA_BOSCH else 2 @@ -192,6 +211,9 @@ class CarState(object): if self.CP.carFingerprint in (CAR.ACCORD, CAR.ACCORD_15, CAR.ACCORDH, CAR.CIVIC_BOSCH): # TODO: find wheels moving bit in dbc self.standstill = cp.vl["ENGINE_DATA"]['XMISSION_SPEED'] < 0.1 self.door_all_closed = not cp.vl["SCM_FEEDBACK"]['DRIVERS_DOOR_OPEN'] + elif self.CP.carFingerprint == CAR.ODYSSEY_CHN: + self.standstill = cp.vl["ENGINE_DATA"]['XMISSION_SPEED'] < 0.1 + self.door_all_closed = not cp.vl["SCM_BUTTONS"]['DRIVERS_DOOR_OPEN'] else: self.standstill = not cp.vl["STANDSTILL"]['WHEELS_MOVING'] self.door_all_closed = not any([cp.vl["DOORS_STATUS"]['DOOR_OPEN_FL'], cp.vl["DOORS_STATUS"]['DOOR_OPEN_FR'], @@ -251,6 +273,9 @@ class CarState(object): if self.CP.carFingerprint in (CAR.CIVIC, CAR.ODYSSEY, CAR.CRV_5G, CAR.ACCORD, CAR.ACCORD_15, CAR.ACCORDH, CAR.CIVIC_BOSCH): self.park_brake = cp.vl["EPB_STATUS"]['EPB_STATE'] != 0 self.main_on = cp.vl["SCM_FEEDBACK"]['MAIN_ON'] + elif self.CP.carFingerprint == CAR.ODYSSEY_CHN: + self.park_brake = cp.vl["EPB_STATUS"]['EPB_STATE'] != 0 + self.main_on = cp.vl["SCM_BUTTONS"]['MAIN_ON'] else: self.park_brake = 0 # TODO self.main_on = cp.vl["SCM_BUTTONS"]['MAIN_ON'] @@ -260,7 +285,7 @@ class CarState(object): self.pedal_gas = cp.vl["POWERTRAIN_DATA"]['PEDAL_GAS'] # crv doesn't include cruise control - if self.CP.carFingerprint in (CAR.CRV, CAR.ODYSSEY, CAR.ACURA_RDX, CAR.RIDGELINE, CAR.PILOT_2019): + if self.CP.carFingerprint in (CAR.CRV, CAR.ODYSSEY, CAR.ACURA_RDX, CAR.RIDGELINE, CAR.PILOT_2019, CAR.ODYSSEY_CHN): self.car_gas = self.pedal_gas else: self.car_gas = cp.vl["GAS_PEDAL_2"]['CAR_GAS'] diff --git a/selfdrive/car/honda/hondacan.py b/selfdrive/car/honda/hondacan.py index 435360d65..8f369feca 100644 --- a/selfdrive/car/honda/hondacan.py +++ b/selfdrive/car/honda/hondacan.py @@ -65,8 +65,8 @@ 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': 0x03, - 'SET_ME_X03_2': 0x03, + '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, } 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 3acd2c741..a9c42d8d8 100755 --- a/selfdrive/car/honda/interface.py +++ b/selfdrive/car/honda/interface.py @@ -286,6 +286,19 @@ class CarInterface(object): ret.longitudinalKiBP = [0., 35.] ret.longitudinalKiV = [0.18, 0.12] + elif candidate == CAR.ODYSSEY_CHN: + stop_and_go = False + ret.mass = 1849.2 + std_cargo # mean of 4 models in kg + ret.wheelbase = 2.90 # spec + ret.centerToFront = ret.wheelbase * 0.41 # from CAR.ODYSSEY + ret.steerRatio = 14.35 # from CAR.ODYSSEY + tire_stiffness_factor = 0.82 # from CAR.ODYSSEY + ret.steerKpV, ret.steerKiV = [[0.45], [0.135]] + ret.longitudinalKpBP = [0., 5., 35.] + ret.longitudinalKpV = [1.2, 0.8, 0.5] + ret.longitudinalKiBP = [0., 35.] + ret.longitudinalKiV = [0.18, 0.12] + elif candidate in (CAR.PILOT, CAR.PILOT_2019): stop_and_go = False ret.mass = 4303 * CV.LB_TO_KG + std_cargo diff --git a/selfdrive/car/honda/values.py b/selfdrive/car/honda/values.py index 56302551f..b1278d4df 100644 --- a/selfdrive/car/honda/values.py +++ b/selfdrive/car/honda/values.py @@ -66,6 +66,7 @@ class CAR: CRV = "HONDA CR-V 2016 TOURING" CRV_5G = "HONDA CR-V 2017 EX" ODYSSEY = "HONDA ODYSSEY 2018 EX-L" + ODYSSEY_CHN = "HONDA ODYSSEY 2019 EXCLUSIVE CHN" ACURA_RDX = "ACURA RDX 2018 ACURAWATCH PLUS" PILOT = "HONDA PILOT 2017 TOURING" PILOT_2019 = "HONDA PILOT 2019 ELITE" @@ -109,6 +110,9 @@ FINGERPRINTS = { { 57: 3, 148: 8, 228: 5, 229: 4, 304: 8, 342: 6, 344: 8, 380: 8, 399: 7, 411: 5, 419: 8, 420: 8, 427: 3, 432: 7, 440: 8, 450: 8, 463: 8, 464: 8, 476: 4, 490: 8, 506: 8, 507: 1, 542: 7, 545: 6, 597: 8, 662: 4, 773: 7, 777: 8, 780: 8, 795: 8, 800: 8, 804: 8, 806: 8, 808: 8, 817: 4, 819: 7, 821: 5, 825: 4, 829: 5, 837: 5, 856: 7, 862: 8, 871: 8, 881: 8, 882: 4, 884: 8, 891: 8, 892: 8, 905: 8, 923: 2, 927: 8, 929: 8, 963: 8, 965: 8, 966: 8, 967: 8, 983: 8, 985: 3, 1029: 8, 1036: 8, 1052: 8, 1064: 7, 1088: 8, 1089: 8, 1092: 1, 1108: 8, 1110: 8, 1125: 8, 1296: 8, 1302: 8, 1600: 5, 1601: 8, 1612: 5, 1613: 5, 1614: 5, 1616: 5, 1619: 5, 1623: 5, 1668: 5 }], + CAR.ODYSSEY_CHN: [{ + 57: 3, 145: 8, 316: 8, 342: 6, 344: 8, 380: 8, 398: 3, 399: 7, 401: 8, 404: 4, 411: 5, 420: 8, 422: 8, 423: 2, 426: 8, 432: 7, 450: 8, 464: 8, 490: 8, 506: 8, 507: 1, 597: 8, 610: 8, 611: 8, 612: 8, 617: 8, 660: 8, 661: 4, 773: 7, 780: 8, 804: 8, 808: 8, 829: 5, 862: 8, 884: 7, 892: 8, 923: 2, 929: 8, 1030: 5, 1137: 8, 1302: 8, 1348: 5, 1361: 5, 1365: 5, 1600: 5, 1601: 8, 1639: 8 + }], # 2017 Pilot Touring AND 2016 Pilot EX-L w/ Added Comma Pedal Support (512L & 513L) CAR.PILOT: [{ 57: 3, 145: 8, 228: 5, 229: 4, 308: 5, 316: 8, 334: 8, 339: 7, 342: 6, 344: 8, 379: 8, 380: 8, 392: 6, 399: 7, 419: 8, 420: 8, 422: 8, 425: 8, 426: 8, 427: 3, 432: 7, 463: 8, 464: 8, 476: 4, 490: 8, 506: 8, 507: 1, 512: 6, 513: 6, 538: 3, 542: 7, 545: 5, 546: 3, 597: 8, 660: 8, 773: 7, 777: 8, 780: 8, 795: 8, 800: 8, 804: 8, 808: 8, 819: 7, 821: 5, 829: 5, 837: 5, 856: 7, 871: 8, 882: 2, 884: 7, 891: 8, 892: 8, 923: 2, 929: 8, 963: 8, 965: 8, 966: 8, 967: 8, 983: 8, 985: 3, 1027: 5, 1029: 8, 1036: 8, 1039: 8, 1064: 7, 1088: 8, 1089: 8, 1108: 8, 1125: 8, 1296: 8, 1424: 5, 1600: 5, 1601: 8, 1612: 5, 1613: 5, 1616: 5, 1618: 5, 1668: 5 @@ -141,6 +145,7 @@ DBC = { CAR.CRV: dbc_dict('honda_crv_touring_2016_can_generated', 'acura_ilx_2016_nidec'), CAR.CRV_5G: dbc_dict('honda_crv_ex_2017_can_generated', None), CAR.ODYSSEY: dbc_dict('honda_odyssey_exl_2018_generated', 'acura_ilx_2016_nidec'), + CAR.ODYSSEY_CHN: dbc_dict('honda_odyssey_extreme_edition_2018_china_can', 'acura_ilx_2016_nidec'), CAR.PILOT: dbc_dict('honda_pilot_touring_2017_can_generated', 'acura_ilx_2016_nidec'), CAR.PILOT_2019: dbc_dict('honda_pilot_touring_2017_can_generated', 'acura_ilx_2016_nidec'), CAR.RIDGELINE: dbc_dict('honda_ridgeline_black_edition_2017_can_generated', 'acura_ilx_2016_nidec'), @@ -157,6 +162,7 @@ STEER_THRESHOLD = { CAR.CRV: 1200, CAR.CRV_5G: 1200, CAR.ODYSSEY: 1200, + CAR.ODYSSEY_CHN: 1200, CAR.PILOT: 1200, CAR.PILOT_2019: 1200, CAR.RIDGELINE: 1200, @@ -173,6 +179,7 @@ SPEED_FACTOR = { CAR.CRV: 1.025, CAR.CRV_5G: 1.025, CAR.ODYSSEY: 1., + CAR.ODYSSEY_CHN: 1., CAR.PILOT: 1., CAR.PILOT_2019: 1., CAR.RIDGELINE: 1., From 7978afabe542289e5a2082491b96c82f85d13765 Mon Sep 17 00:00:00 2001 From: eFini Date: Wed, 10 Apr 2019 10:35:57 +1000 Subject: [PATCH 6/6] Add port for 2019 Honda CRV Hybrid (China ver) (#596) * 2019 honda crv hybrid port (china version) * adjust mass based on spec * update mass based on spec * add 2019 Honda CRV Hybrid --- README.md | 1 + selfdrive/car/honda/carstate.py | 20 ++++++++++++++------ selfdrive/car/honda/interface.py | 14 ++++++++++++++ selfdrive/car/honda/values.py | 9 ++++++++- 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index f63d6bcd7..a82b98dbc 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,7 @@ Supported Cars | Honda | Civic Hatchback 2017-19 | Honda Sensing | Yes | Stock | 0mph | 12mph | Bosch | | Honda | CR-V 2015-16 | Touring | Yes | Yes | 25mph1| 12mph | Nidec | | Honda | CR-V 2017-18 | Honda Sensing | Yes | Stock | 0mph | 12mph | Bosch | +| Honda | CR-V Hybrid 2019 | All | Yes | Stock | 0mph | 12mph | Bosch | | Honda | Odyssey 2017-19 | Honda Sensing | Yes | Yes | 25mph1| 0mph | Inverted Nidec | | Honda | Pilot 2016-18 | Honda Sensing | Yes | Yes | 25mph1| 12mph | Nidec | | Honda | Pilot 2019 | All | Yes | Yes | 25mph1| 12mph | Inverted Nidec | diff --git a/selfdrive/car/honda/carstate.py b/selfdrive/car/honda/carstate.py index c3ef71b5e..b8164e8c5 100644 --- a/selfdrive/car/honda/carstate.py +++ b/selfdrive/car/honda/carstate.py @@ -60,7 +60,6 @@ def get_can_signals(CP): ("ENGINE_DATA", 100), ("WHEEL_SPEEDS", 50), ("STEERING_SENSORS", 100), - ("GEARBOX", 100), ("SEATBELT_STATUS", 10), ("CRUISE", 10), ("POWERTRAIN_DATA", 100), @@ -78,9 +77,18 @@ def get_can_signals(CP): ("SCM_BUTTONS", 25), ] + if CP.carFingerprint == CAR.CRV_HYBRID: + checks += [ + ("GEARBOX", 50), + ] + else: + checks += [ + ("GEARBOX", 100), + ] + if CP.radarOffCan: # Civic is only bosch to use the same brake message as other hondas. - if CP.carFingerprint not in (CAR.ACCORDH, CAR.CIVIC_BOSCH): + if CP.carFingerprint not in (CAR.ACCORDH, CAR.CIVIC_BOSCH, CAR.CRV_HYBRID): signals += [("BRAKE_PRESSED", "BRAKE_MODULE", 0)] checks += [("BRAKE_MODULE", 50)] signals += [("CAR_GAS", "GAS_PEDAL_2", 0), @@ -101,7 +109,7 @@ def get_can_signals(CP): else: checks += [("CRUISE_PARAMS", 50)] - if CP.carFingerprint in (CAR.ACCORD, CAR.ACCORD_15, CAR.ACCORDH, CAR.CIVIC_BOSCH): + if CP.carFingerprint in (CAR.ACCORD, CAR.ACCORD_15, CAR.ACCORDH, CAR.CIVIC_BOSCH, CAR.CRV_HYBRID): signals += [("DRIVERS_DOOR_OPEN", "SCM_FEEDBACK", 1)] elif CP.carFingerprint == CAR.ODYSSEY_CHN: signals += [("DRIVERS_DOOR_OPEN", "SCM_BUTTONS", 1)] @@ -208,7 +216,7 @@ class CarState(object): # ******************* parse out can ******************* - if self.CP.carFingerprint in (CAR.ACCORD, CAR.ACCORD_15, CAR.ACCORDH, CAR.CIVIC_BOSCH): # TODO: find wheels moving bit in dbc + if self.CP.carFingerprint in (CAR.ACCORD, CAR.ACCORD_15, CAR.ACCORDH, CAR.CIVIC_BOSCH, CAR.CRV_HYBRID): # TODO: find wheels moving bit in dbc self.standstill = cp.vl["ENGINE_DATA"]['XMISSION_SPEED'] < 0.1 self.door_all_closed = not cp.vl["SCM_FEEDBACK"]['DRIVERS_DOOR_OPEN'] elif self.CP.carFingerprint == CAR.ODYSSEY_CHN: @@ -270,7 +278,7 @@ class CarState(object): self.right_blinker_on = cp.vl["SCM_FEEDBACK"]['RIGHT_BLINKER'] self.brake_hold = cp.vl["VSA_STATUS"]['BRAKE_HOLD_ACTIVE'] - if self.CP.carFingerprint in (CAR.CIVIC, CAR.ODYSSEY, CAR.CRV_5G, CAR.ACCORD, CAR.ACCORD_15, CAR.ACCORDH, CAR.CIVIC_BOSCH): + if self.CP.carFingerprint in (CAR.CIVIC, CAR.ODYSSEY, CAR.CRV_5G, CAR.ACCORD, CAR.ACCORD_15, CAR.ACCORDH, CAR.CIVIC_BOSCH, CAR.CRV_HYBRID): self.park_brake = cp.vl["EPB_STATUS"]['EPB_STATE'] != 0 self.main_on = cp.vl["SCM_FEEDBACK"]['MAIN_ON'] elif self.CP.carFingerprint == CAR.ODYSSEY_CHN: @@ -298,7 +306,7 @@ class CarState(object): if self.CP.radarOffCan: self.stopped = cp.vl["ACC_HUD"]['CRUISE_SPEED'] == 252. self.cruise_speed_offset = calc_cruise_offset(0, self.v_ego) - if self.CP.carFingerprint in (CAR.CIVIC_BOSCH, CAR.ACCORDH): + if self.CP.carFingerprint in (CAR.CIVIC_BOSCH, CAR.ACCORDH, CAR.CRV_HYBRID): self.brake_switch = cp.vl["POWERTRAIN_DATA"]['BRAKE_SWITCH'] self.brake_pressed = cp.vl["POWERTRAIN_DATA"]['BRAKE_PRESSED'] or \ (self.brake_switch and self.brake_switch_prev and \ diff --git a/selfdrive/car/honda/interface.py b/selfdrive/car/honda/interface.py index a9c42d8d8..4072b0354 100755 --- a/selfdrive/car/honda/interface.py +++ b/selfdrive/car/honda/interface.py @@ -260,6 +260,20 @@ class CarInterface(object): ret.longitudinalKiBP = [0., 35.] ret.longitudinalKiV = [0.18, 0.12] + elif candidate == CAR.CRV_HYBRID: + stop_and_go = True + ret.safetyParam = 1 # Accord and CRV 5G use an alternate user brake msg + ret.mass = 1667. + std_cargo # mean of 4 models in kg + ret.wheelbase = 2.66 + ret.centerToFront = ret.wheelbase * 0.41 + ret.steerRatio = 16.0 # 12.3 is spec end-to-end + tire_stiffness_factor = 0.677 + ret.steerKpV, ret.steerKiV = [[0.6], [0.18]] + ret.longitudinalKpBP = [0., 5., 35.] + ret.longitudinalKpV = [1.2, 0.8, 0.5] + ret.longitudinalKiBP = [0., 35.] + ret.longitudinalKiV = [0.18, 0.12] + elif candidate == CAR.ACURA_RDX: stop_and_go = False ret.mass = 3935 * CV.LB_TO_KG + std_cargo diff --git a/selfdrive/car/honda/values.py b/selfdrive/car/honda/values.py index b1278d4df..f106ccab3 100644 --- a/selfdrive/car/honda/values.py +++ b/selfdrive/car/honda/values.py @@ -65,6 +65,7 @@ class CAR: ACURA_ILX = "ACURA ILX 2016 ACURAWATCH PLUS" CRV = "HONDA CR-V 2016 TOURING" CRV_5G = "HONDA CR-V 2017 EX" + CRV_HYBRID = "HONDA CR-V 2019 HYBRID" ODYSSEY = "HONDA ODYSSEY 2018 EX-L" ODYSSEY_CHN = "HONDA ODYSSEY 2019 EXCLUSIVE CHN" ACURA_RDX = "ACURA RDX 2018 ACURAWATCH PLUS" @@ -102,6 +103,9 @@ FINGERPRINTS = { CAR.CRV_5G: [{ 57: 3, 148: 8, 199: 4, 228: 5, 231: 5, 232: 7, 304: 8, 330: 8, 340: 8, 344: 8, 380: 8, 399: 7, 401: 8, 420: 8, 423: 2, 427: 3, 428: 8, 432: 7, 441: 5, 446: 3, 450: 8, 464: 8, 467: 2, 469: 3, 470: 2, 474: 8, 476: 7, 477: 8, 479: 8, 490: 8, 493: 5, 495: 8, 507: 1, 545: 6, 597: 8, 661: 4, 662: 4, 773: 7, 777: 8, 780: 8, 795: 8, 800: 8, 804: 8, 806: 8, 808: 8, 814: 4, 815: 8, 817: 4, 825: 4, 829: 5, 862: 8, 881: 8, 882: 4, 884: 8, 888: 8, 891: 8, 927: 8, 918: 7, 929: 8, 983: 8, 985: 3, 1024: 5, 1027: 5, 1029: 8, 1036: 8, 1039: 8, 1064: 7, 1108: 8, 1092: 1, 1115: 4, 1125: 8, 1127: 2, 1296: 8, 1302: 8, 1322: 5, 1361: 5, 1365: 5, 1424: 5, 1600: 5, 1601: 8, 1618: 5, 1633: 8, 1670: 5 }], + CAR.CRV_HYBRID: [{ + 57: 3, 148: 8, 228: 5, 304: 8, 330: 8, 344: 8, 380: 8, 387: 8, 388: 8, 399: 7, 419: 8, 420: 8, 427: 3, 432: 7, 441: 5, 450: 8, 464: 8, 477: 8, 479: 8, 490: 8, 495: 8, 525: 8, 531: 8, 545: 6, 662: 4, 773: 7, 777: 8, 780: 8, 804: 8, 806: 8, 808: 8, 814: 4, 829: 5, 833: 6, 862: 8, 884: 8, 891: 8, 927: 8, 929: 8, 1302: 8, 1361: 5, 1365: 5, 1600: 5, 1601: 8 + }], # 2018 Odyssey w/ Added Comma Pedal Support (512L & 513L) CAR.ODYSSEY: [{ 57: 3, 148: 8, 228: 5, 229: 4, 316: 8, 342: 6, 344: 8, 380: 8, 399: 7, 411: 5, 419: 8, 420: 8, 427: 3, 432: 7, 450: 8, 463: 8, 464: 8, 476: 4, 490: 8, 506: 8, 512: 6, 513: 6, 542: 7, 545: 6, 597: 8, 662: 4, 773: 7, 777: 8, 780: 8, 795: 8, 800: 8, 804: 8, 806: 8, 808: 8, 817: 4, 819: 7, 821: 5, 825: 4, 829: 5, 837: 5, 856: 7, 862: 8, 871: 8, 881: 8, 882: 4, 884: 8, 891: 8, 892: 8, 905: 8, 923: 2, 927: 8, 929: 8, 963: 8, 965: 8, 966: 8, 967: 8, 983: 8, 985: 3, 1029: 8, 1036: 8, 1052: 8, 1064: 7, 1088: 8, 1089: 8, 1092: 1, 1108: 8, 1110: 8, 1125: 8, 1296: 8, 1302: 8, 1600: 5, 1601: 8, 1612: 5, 1613: 5, 1614: 5, 1615: 8, 1616: 5, 1619: 5, 1623: 5, 1668: 5 @@ -144,6 +148,7 @@ DBC = { CAR.CIVIC_BOSCH: dbc_dict('honda_civic_hatchback_ex_2017_can_generated', None), CAR.CRV: dbc_dict('honda_crv_touring_2016_can_generated', 'acura_ilx_2016_nidec'), CAR.CRV_5G: dbc_dict('honda_crv_ex_2017_can_generated', None), + CAR.CRV_HYBRID: dbc_dict('honda_crv_hybrid_2019_can_generated', None), CAR.ODYSSEY: dbc_dict('honda_odyssey_exl_2018_generated', 'acura_ilx_2016_nidec'), CAR.ODYSSEY_CHN: dbc_dict('honda_odyssey_extreme_edition_2018_china_can', 'acura_ilx_2016_nidec'), CAR.PILOT: dbc_dict('honda_pilot_touring_2017_can_generated', 'acura_ilx_2016_nidec'), @@ -161,6 +166,7 @@ STEER_THRESHOLD = { CAR.CIVIC_BOSCH: 1200, CAR.CRV: 1200, CAR.CRV_5G: 1200, + CAR.CRV_HYBRID: 1200, CAR.ODYSSEY: 1200, CAR.ODYSSEY_CHN: 1200, CAR.PILOT: 1200, @@ -178,6 +184,7 @@ SPEED_FACTOR = { CAR.CIVIC_BOSCH: 1., CAR.CRV: 1.025, CAR.CRV_5G: 1.025, + CAR.CRV_HYBRID: 1.025, CAR.ODYSSEY: 1., CAR.ODYSSEY_CHN: 1., CAR.PILOT: 1., @@ -186,4 +193,4 @@ SPEED_FACTOR = { } # TODO: get these from dbc file -HONDA_BOSCH = [CAR.ACCORD, CAR.ACCORD_15, CAR.ACCORDH, CAR.CIVIC_BOSCH, CAR.CRV_5G] +HONDA_BOSCH = [CAR.ACCORD, CAR.ACCORD_15, CAR.ACCORDH, CAR.CIVIC_BOSCH, CAR.CRV_5G, CAR.CRV_HYBRID]