diff --git a/README.md b/README.md
index f63d6bcd72..a82b98dbc2 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 c3ef71b5ee..b8164e8c52 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 a9c42d8d80..4072b03548 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 b1278d4df8..f106ccab34 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]