diff --git a/README.md b/README.md index f9a91e8f0394b1..bc17fec979b153 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,10 @@ Community WIP Cars - [Classic Tesla Model S (pre-AP)](https://github.com/commaai/openpilot/pull/145) +- [Honda Odyssey 2018 EX-L with Honda Sensing](https://github.com/commaai/openpilot/pull/155) + +- [Honda Pilot 2017 Touring](https://github.com/commaai/openpilot/pull/159) + Directory structure ------ diff --git a/common/fingerprints.py b/common/fingerprints.py index 9881115b69cd7f..aa116e70ebeff8 100644 --- a/common/fingerprints.py +++ b/common/fingerprints.py @@ -16,12 +16,18 @@ # sent messages 0x194: 4, 0x1fa: 8, 0x30c: 8, 0x33d: 5, }, + "HONDA PILOT 2017 TOURING": { + 57L: 3, 145L: 8, 228L: 5, 229L: 4, 308L: 5, 316L: 8, 334L: 8, 342L: 6, 344L: 8, 379L: 8, 380L: 8, 399L: 7, 419L: 8, 420L: 8, 422L: 8, 425L: 8, 426L: 8, 427L: 3, 432L: 7, 463L: 8, 464L: 8, 476L: 4, 490L: 8, 506L: 8, 507L: 1, 538L: 3, 542L: 7, 545L: 5, 546L: 3, 597L: 8, 660L: 8, 768L: 8, 769L: 8, 773L: 7, 777L: 8, 780L: 8, 795L: 8, 800L: 8, 804L: 8, 808L: 8, 819L: 7, 821L: 5, 829L: 5, 837L: 5, 856L: 7, 871L: 8, 882L: 2, 884L: 7, 891L: 8, 892L: 8, 923L: 2, 929L: 8, 963L: 8, 965L: 8, 966L: 8, 967L: 8, 983L: 8, 985L: 3, 1024L: 8, 1027L: 5, 1029L: 8, 1036L: 8, 1040L: 8, 1041L: 8, 1042L: 8, 1043L: 8, 1044L: 8, 1045L: 8, 1046L: 8, 1047L: 8, 1056L: 8, 1057L: 8, 1058L: 8, 1059L: 8, 1060L: 8, 1064L: 7, 1072L: 8, 1073L: 8, 1074L: 8, 1075L: 8, 1076L: 8, 1077L: 8, 1078L: 8, 1079L: 8, 1080L: 8, 1081L: 8, 1088L: 8, 1089L: 8, 1090L: 8, 1091L: 8, 1092L: 8, 1093L: 8, 1108L: 8, 1125L: 8, 1279L: 8, 1280L: 8, 1296L: 8, 1297L: 8, 1424L: 5, 1600L: 5, 1601L: 8, 1612L: 5, 1613L: 5, 1616L: 5, 1618L: 5, 1668L: 5 + }, "TOYOTA RAV4 2017": { 36L: 8, 37L: 8, 170L: 8, 180L: 8, 186L: 4, 426L: 6, 452L: 8, 464L: 8, 466L: 8, 467L: 8, 547L: 8, 548L: 8, 552L: 4, 562L: 4, 608L: 8, 610L: 5, 643L: 7, 705L: 8, 725L: 2, 740L: 5, 800L: 8, 835L: 8, 836L: 8, 849L: 4, 869L: 7, 870L: 7, 871L: 2, 896L: 8, 897L: 8, 900L: 6, 902L: 6, 905L: 8, 911L: 8, 916L: 3, 918L: 7, 921L: 8, 933L: 8, 944L: 8, 945L: 8, 951L: 8, 955L: 4, 956L: 8, 979L: 2, 998L: 5, 999L: 7, 1000L: 8, 1001L: 8, 1008L: 2, 1014L: 8, 1017L: 8, 1041L: 8, 1042L: 8, 1043L: 8, 1044L: 8, 1056L: 8, 1059L: 1, 1114L: 8, 1161L: 8, 1162L: 8, 1163L: 8, 1176L: 8, 1177L: 8, 1178L: 8, 1179L: 8, 1180L: 8, 1181L: 8, 1190L: 8, 1191L: 8, 1192L: 8, 1196L: 8, 1227L: 8, 1228L: 8, 1235L: 8, 1237L: 8, 1263L: 8, 1279L: 8, 1408L: 8, 1409L: 8, 1410L: 8, 1552L: 8, 1553L: 8, 1554L: 8, 1555L: 8, 1556L: 8, 1557L: 8, 1561L: 8, 1562L: 8, 1568L: 8, 1569L: 8, 1570L: 8, 1571L: 8, 1572L: 8, 1584L: 8, 1589L: 8, 1592L: 8, 1593L: 8, 1595L: 8, 1596L: 8, 1597L: 8, 1600L: 8, 1656L: 8, 1664L: 8, 1728L: 8, 1745L: 8, 1779L: 8, 1904L: 8, 1912L: 8, 1990L: 8, 1998L: 8 }, "TOYOTA PRIUS 2017": { 36L: 8, 37L: 8, 166L: 8, 170L: 8, 180L: 8, 295L: 8, 296L: 8, 426L: 6, 452L: 8, 466L: 8, 467L: 8, 550L: 8, 552L: 4, 560L: 7, 562L: 6, 581L: 5, 608L: 8, 610L: 8, 614L: 8, 643L: 7, 658L: 8, 713L: 8, 740L: 5, 742L: 8, 743L: 8, 800L: 8, 810L: 2, 814L: 8, 829L: 2, 830L: 7, 835L: 8, 836L: 8, 863L: 8, 869L: 7, 870L: 7, 871L: 2, 898L: 8, 900L: 6, 902L: 6, 905L: 8, 918L: 8, 921L: 8, 933L: 8, 944L: 8, 945L: 8, 950L: 8, 951L: 8, 953L: 8, 955L: 8, 956L: 8, 971L: 7, 975L: 5, 993L: 8, 998L: 5, 999L: 7, 1000L: 8, 1001L: 8, 1014L: 8, 1017L: 8, 1020L: 8, 1041L: 8, 1042L: 8, 1044L: 8, 1056L: 8, 1057L: 8, 1059L: 1, 1071L: 8, 1077L: 8, 1082L: 8, 1083L: 8, 1084L: 8, 1085L: 8, 1086L: 8, 1114L: 8, 1132L: 8, 1161L: 8, 1162L: 8, 1163L: 8, 1175L: 8, 1227L: 8, 1228L: 8, 1235L: 8, 1237L: 8, 1279L: 8, 1552L: 8, 1553L: 8, 1556L: 8, 1557L: 8, 1568L: 8, 1570L: 8, 1571L: 8, 1572L: 8, 1595L: 8, 1777L: 8, 1779L: 8, 1904L: 8, 1912L: 8, 1990L: 8, 1998L: 8 }, + "HONDA ODYSSEY 2018 EX-L": { + 57L: 3, 148L: 8, 228L: 5, 229L: 4, 316L: 8, 342L: 6, 344L: 8, 380L: 8, 399L: 7, 411L: 5, 419L: 8, 420L: 8, 427L: 3, 432L: 7, 450L: 8, 463L: 8, 464L: 8, 476L: 4, 490L: 8, 506L: 8, 542L: 7, 545L: 4, 597L: 8, 662L: 4, 773L: 7, 777L: 8, 780L: 8, 795L: 8, 800L: 8, 804L: 8, 806L: 8, 808L: 8, 817L: 4, 819L: 7, 821L: 5, 825L: 4, 829L: 5, 837L: 5, 856L: 7, 862L: 8, 871L: 8, 881L: 8, 882L: 4, 884L: 8, 891L: 8, 892L: 8, 905L: 8, 923L: 2, 927L: 8, 929L: 8, 963L: 8, 965L: 8, 966L: 8, 967L: 8, 983L: 8, 985L: 3, 1029L: 8, 1036L: 8, 1052L: 8, 1064L: 7, 1088L: 8, 1089L: 8, 1092L: 1, 1108L: 8, 1110L: 8, 1125L: 8, 1296L: 8, 1302L: 8, 1600L: 5, 1601L: 8, 1612L: 5, 1613L: 5, 1614L: 5, 1615L: 8, 1616L: 5, 1619L: 5, 1623L: 5, 1668L: 5 + } } # support additional internal only fingerprints @@ -56,4 +62,3 @@ def eliminate_incompatible_cars(msg, candidate_cars): def all_known_cars(): """Returns a list of all known car strings.""" return _FINGERPRINTS.keys() - diff --git a/selfdrive/car/honda/carcontroller.py b/selfdrive/car/honda/carcontroller.py index 287deccb581170..ea316264b70541 100644 --- a/selfdrive/car/honda/carcontroller.py +++ b/selfdrive/car/honda/carcontroller.py @@ -169,16 +169,16 @@ def update(self, sendcan, enabled, CS, frame, actuators, \ # Send dashboard UI commands. if (frame % 10) == 0: idx = (frame/10) % 4 - can_sends.extend(hondacan.create_ui_commands(pcm_speed, hud, CS.civic, CS.accord, CS.crv, idx)) + can_sends.extend(hondacan.create_ui_commands(pcm_speed, hud, CS.civic, CS.accord, CS.crv, CS.odyssey, idx)) # radar at 20Hz, but these msgs need to be sent at 50Hz on ilx (seems like an Acura bug) - if CS.civic or CS.accord or CS.crv: - radar_send_step = 5 - else: + if CS.acura: radar_send_step = 2 + else: + radar_send_step = 5 if (frame % radar_send_step) == 0: idx = (frame/radar_send_step) % 4 - can_sends.extend(hondacan.create_radar_commands(CS.v_ego, CS.civic, CS.accord, CS.crv, idx)) + can_sends.extend(hondacan.create_radar_commands(CS.v_ego, CS.civic, CS.accord, CS.crv, CS.odyssey, idx)) sendcan.send(can_list_to_can_capnp(can_sends, msgtype='sendcan').to_bytes()) diff --git a/selfdrive/car/honda/carstate.py b/selfdrive/car/honda/carstate.py index 6ade91d580b2cb..5fe960c60a67bf 100644 --- a/selfdrive/car/honda/carstate.py +++ b/selfdrive/car/honda/carstate.py @@ -106,7 +106,7 @@ def get_can_signals(CP): (0x405, 3), ] - elif CP.carFingerprint == "ACURA ILX 2016 ACURAWATCH PLUS": + elif CP.carFingerprint == "ACURA ILX 2016 ACURAWATCH PLUS" or "HONDA PILOT 2017 TOURING": dbc_f = 'acura_ilx_2016_can.dbc' signals = [ ("XMISSION_SPEED", 0x158, 0), @@ -262,6 +262,59 @@ def get_can_signals(CP): (0x324, 10), (0x405, 3), ] + elif CP.carFingerprint == "HONDA ODYSSEY 2018 EX-L": + dbc_f = 'honda_odyssey_exl_2018.dbc' + signals = [ + ("XMISSION_SPEED", 0x158, 0), + ("WHEEL_SPEED_FL", 0x1d0, 0), + ("WHEEL_SPEED_FR", 0x1d0, 0), + ("WHEEL_SPEED_RL", 0x1d0, 0), + ("WHEEL_SPEED_RR", 0x1d0, 0), + ("STEER_ANGLE", 0x156, 0), + ("STEER_ANGLE_RATE", 0x156, 0), + ("STEER_TORQUE_SENSOR", 0x18f, 0), + ("GEAR", 0x1a3, 0), + ("WHEELS_MOVING", 0x1b0, 1), + ("DOOR_OPEN_FL", 0x405, 1), + ("DOOR_OPEN_FR", 0x405, 1), + ("DOOR_OPEN_RL", 0x405, 1), + ("DOOR_OPEN_RR", 0x405, 1), + ("CRUISE_SPEED_PCM", 0x324, 0), + ("SEATBELT_DRIVER_LAMP", 0x305, 1), + ("SEATBELT_DRIVER_LATCHED", 0x305, 0), + ("BRAKE_PRESSED", 0x17c, 0), + ("BRAKE_SWITCH", 0x17c, 0), + ("CRUISE_BUTTONS", 0x296, 0), + ("ESP_DISABLED", 0x1a4, 1), + ("HUD_LEAD", 0x30c, 0), + ("USER_BRAKE", 0x1a4, 0), + ("STEER_STATUS", 0x18f, 5), + ("BRAKE_ERROR_1", 0x1b0, 1), + ("BRAKE_ERROR_2", 0x1b0, 1), + ("GEAR_SHIFTER", 0x1a3, 0), + ("MAIN_ON", 0x1a6, 0), + ("ACC_STATUS", 0x17c, 0), + ("PEDAL_GAS", 0x17c, 0), + ("CRUISE_SETTING", 0x296, 0), + ("LEFT_BLINKER", 0x326, 0), + ("RIGHT_BLINKER", 0x326, 0), + ("CRUISE_SPEED_OFFSET", 0x37c, 0) + ] + checks = [ + (0x156, 100), + (0x158, 100), + (0x17c, 100), + (0x1a3, 50), + (0x1a4, 50), + (0x1b0, 50), + (0x1d0, 50), + (0x296, 25), + (0x305, 10), + (0x324, 10), + (0x326, 10), + (0x37c, 10), + (0x405, 3), + ] # add gas interceptor reading if we are using it if CP.enableGas: signals.append(("INTERCEPTOR_GAS", 0x201, 0)) @@ -279,6 +332,8 @@ def __init__(self, CP): self.civic = False self.accord = False self.crv = False + self.odyssey = False + self.pilot = False if CP.carFingerprint == "HONDA CIVIC 2016 TOURING": self.civic = True elif CP.carFingerprint == "ACURA ILX 2016 ACURAWATCH PLUS": @@ -287,6 +342,8 @@ def __init__(self, CP): self.accord = True elif CP.carFingerprint == "HONDA CR-V 2016 TOURING": self.crv = True + elif CP.carFingerprint == "HONDA ODYSSEY 2018 EX-L": + self.odyssey = True else: raise ValueError("unsupported car %s" % CP.carFingerprint) @@ -419,6 +476,20 @@ def update(self, cp): self.cruise_speed_offset = -0.3 self.park_brake = 0 # TODO self.brake_hold = 0 # TODO + elif self.odyssey: + can_gear_shifter = cp.vl[0x1A3]['GEAR_SHIFTER'] + self.angle_steers = cp.vl[0x156]['STEER_ANGLE'] + self.angle_steers_rate = cp.vl[0x156]['STEER_ANGLE_RATE'] + self.gear = cp.vl[0x1A3]['GEAR'] + self.cruise_setting = cp.vl[0x296]['CRUISE_SETTING'] + self.cruise_buttons = cp.vl[0x296]['CRUISE_BUTTONS'] + self.main_on = cp.vl[0x326]['MAIN_ON'] + self.blinker_on = cp.vl[0x326]['LEFT_BLINKER'] or cp.vl[0x326]['RIGHT_BLINKER'] + self.left_blinker_on = cp.vl[0x326]['LEFT_BLINKER'] + self.right_blinker_on = cp.vl[0x326]['RIGHT_BLINKER'] + self.cruise_speed_offset = calc_cruise_offset(cp.vl[0x37c]['CRUISE_SPEED_OFFSET'], self.v_ego) + self.park_brake = cp.vl[0x1c2]['EPB_STATE'] != 0 + self.brake_hold = cp.vl[0x1A4]['BRAKE_HOLD_ACTIVE'] elif self.acura: can_gear_shifter = cp.vl[0x1A3]['GEAR_SHIFTER'] self.angle_steers = cp.vl[0x156]['STEER_ANGLE'] diff --git a/selfdrive/car/honda/hondacan.py b/selfdrive/car/honda/hondacan.py index 31615a8cbbe0b2..9a8a3f30d49d0c 100644 --- a/selfdrive/car/honda/hondacan.py +++ b/selfdrive/car/honda/hondacan.py @@ -79,7 +79,7 @@ def create_steering_control(apply_steer, crv, idx): commands.append(make_can_msg(0xe4, msg_0xe4, idx, 0)) return commands -def create_ui_commands(pcm_speed, hud, civic, accord, crv, idx): +def create_ui_commands(pcm_speed, hud, civic, accord, crv, odyssey, idx): """Creates an iterable of CAN messages for the UIs.""" commands = [] pcm_speed_real = np.clip(int(round(pcm_speed / 0.002759506)), 0, @@ -90,17 +90,17 @@ def create_ui_commands(pcm_speed, hud, civic, accord, crv, idx): msg_0x33d = chr(hud.X5) + chr(hud.lanes) + chr(hud.beep) + chr(hud.X8) commands.append(make_can_msg(0x33d, msg_0x33d, idx, 0)) - if civic: # 2 more msgs + if civic or odyssey: # 2 more msgs msg_0x35e = chr(0) * 7 commands.append(make_can_msg(0x35e, msg_0x35e, idx, 0)) - if civic or accord: + if civic or accord or odyssey: msg_0x39f = ( chr(0) * 2 + chr(hud.acc_alert) + chr(0) + chr(0xff) + chr(0x7f) + chr(0) ) commands.append(make_can_msg(0x39f, msg_0x39f, idx, 0)) return commands -def create_radar_commands(v_ego, civic, accord, crv, idx): +def create_radar_commands(v_ego, civic, accord, crv, odyssey, idx): """Creates an iterable of CAN messages for the radar system.""" commands = [] v_ego_kph = np.clip(int(round(v_ego * CV.MS_TO_KPH)), 0, 255) @@ -122,6 +122,12 @@ def create_radar_commands(v_ego, civic, accord, crv, idx): elif crv: msg_0x301 = "\x00\x00\x50\x02\x51\x00\x00" commands.append(make_can_msg(0x300, msg_0x300, idx, 1)) + elif odyssey: + msg_0x301 = "\x00\x00\x56\x02\x55\x00\x00" + commands.append(make_can_msg(0x300, msg_0x300, idx, 1)) + elif pilot: + msg_0x301 = "\x00\x00\x56\x02\x58\x00\x00" + commands.append(make_can_msg(0x300, msg_0x300, idx, 1)) else: msg_0x301 = "\x0f\x18\x51\x02\x5a\x00\x00" commands.append(make_can_msg(0x300, msg_0x300, idx, 1)) diff --git a/selfdrive/car/honda/interface.py b/selfdrive/car/honda/interface.py index 90eca2b38dda3b..0c0235e7816ec1 100755 --- a/selfdrive/car/honda/interface.py +++ b/selfdrive/car/honda/interface.py @@ -204,6 +204,32 @@ def get_params(candidate, fingerprint): ret.longitudinalKpV = [1.2, 0.8, 0.5] ret.longitudinalKiBP = [0., 35.] ret.longitudinalKiV = [0.18, 0.12] + elif candidate == "HONDA ODYSSEY 2018 EX-L": + stop_and_go = False + ret.m = 4354./2.205 + std_cargo + ret.l = 3.00 + # Wtf are these? + ret.aF = ret.l * 0.41 + ret.sR = 15.3 + ret.steerKp, ret.steerKi = 0.8, 0.24 + + 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 == "HONDA PILOT 2017 TOURING": + stop_and_go = False + ret.m = 4303./2.205 + std_cargo + ret.l = 3.00 + ret.aF = ret.l * 0.41 + ret.sR = 15.3 + ret.steerKp, ret.steerKi = 0.8, 0.24 + + ret.longitudinalKpBP = [0., 5., 35.] + ret.longitudinalKpV = [1.2, 0.8, 0.5] + ret.longitudinalKiBP = [0., 35.] + ret.longitudinalKiV = [0.18, 0.12] else: raise ValueError("unsupported car %s" % candidate)