diff --git a/README.md b/README.md index f8052b285..a82b98dbc 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 | @@ -76,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 | @@ -83,7 +85,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| 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 diff --git a/panda/board/safety/safety_chrysler.h b/panda/board/safety/safety_chrysler.h index b1c6a743f..4af588401 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 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 +} + 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 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..b8164e8c5 100644 --- a/selfdrive/car/honda/carstate.py +++ b/selfdrive/car/honda/carstate.py @@ -60,18 +60,35 @@ 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.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), @@ -85,11 +102,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 in (CAR.ACCORD, CAR.ACCORD_15, CAR.ACCORDH, CAR.CIVIC_BOSCH): + 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, CAR.CRV_HYBRID): 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 +137,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 +157,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 @@ -189,9 +216,12 @@ 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: + 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'], @@ -248,9 +278,12 @@ 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: + 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 +293,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'] @@ -273,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/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..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 @@ -286,6 +300,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..f106ccab3 100644 --- a/selfdrive/car/honda/values.py +++ b/selfdrive/car/honda/values.py @@ -65,7 +65,9 @@ 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" PILOT = "HONDA PILOT 2017 TOURING" PILOT_2019 = "HONDA PILOT 2019 ELITE" @@ -101,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 @@ -109,6 +114,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 @@ -140,7 +148,9 @@ 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'), 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'), @@ -156,7 +166,9 @@ 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, CAR.PILOT_2019: 1200, CAR.RIDGELINE: 1200, @@ -172,11 +184,13 @@ 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., CAR.PILOT_2019: 1., CAR.RIDGELINE: 1., } # 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]