Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Honda: Port 2024 Integra #32056

Closed
wants to merge 27 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion panda
25 changes: 21 additions & 4 deletions selfdrive/car/honda/carcontroller.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,11 +203,28 @@ def update(self, CC, CS, now_nanos):
if not self.CP.openpilotLongitudinalControl:
if self.frame % 2 == 0 and self.CP.carFingerprint not in HONDA_BOSCH_RADARLESS: # radarless cars don't have supplemental message
can_sends.append(hondacan.create_bosch_supplemental_1(self.packer, self.CAN, self.CP.carFingerprint))
# If using stock ACC, spam cancel command to kill gas when OP disengages.
# Buttons: spam the cancel or resume buttons.
cruise = None
setting = CruiseButtons.NONE
if pcm_cancel_cmd:
can_sends.append(hondacan.spam_buttons_command(self.packer, self.CAN, CruiseButtons.CANCEL, self.CP.carFingerprint))
elif CC.cruiseControl.resume:
can_sends.append(hondacan.spam_buttons_command(self.packer, self.CAN, CruiseButtons.RES_ACCEL, self.CP.carFingerprint))
cruise = CruiseButtons.CANCEL
elif self.CP.carFingerprint not in HONDA_BOSCH_RADARLESS and CC.cruiseControl.resume:
cruise = CruiseButtons.RES_ACCEL
elif self.CP.carFingerprint in HONDA_BOSCH_RADARLESS and CC.enabled and self.frame % 4 == 0:
# Send buttons to the camera when engaged. Only send the LKAS button to turn off stock LKAS off so it can't disengage cruise.
# Priority: pcm_cancel > user > auto resume > turn off lkas > none/idle
cruise = CruiseButtons.NONE
if CS.cruise_buttons or (CS.cruise_setting and CS.cruise_setting != CruiseButtons.LKAS):
cruise = CS.cruise_buttons
setting = CS.cruise_setting
# simulate a momentary press
elif self.frame % 100 <= 25:
if CC.cruiseControl.resume:
cruise = CruiseButtons.RES_ACCEL
elif CS.lkas_hud['ENABLED']:
setting = CruiseButtons.LKAS
if cruise is not None:
can_sends.append(hondacan.create_buttons_command(self.packer, self.CAN, cruise, setting, CS.scm_buttons, self.CP.carFingerprint))

else:
# Send gas and brake commands.
Expand Down
42 changes: 31 additions & 11 deletions selfdrive/car/honda/carstate.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,14 @@
from openpilot.selfdrive.car.honda.hondacan import CanBus, get_cruise_speed_conversion
from openpilot.selfdrive.car.honda.values import CAR, DBC, STEER_THRESHOLD, HONDA_BOSCH, \
HONDA_NIDEC_ALT_SCM_MESSAGES, HONDA_BOSCH_RADARLESS, \
HondaFlags
HondaFlags, GearShifter
from openpilot.selfdrive.car.interfaces import CarStateBase

TransmissionType = car.CarParams.TransmissionType


def get_can_messages(CP, gearbox_msg):
messages = [
("ENGINE_DATA", 100),
("WHEEL_SPEEDS", 50),
("STEERING_SENSORS", 100),
("SEATBELT_STATUS", 10),
Expand All @@ -38,8 +37,11 @@ def get_can_messages(CP, gearbox_msg):
("SCM_FEEDBACK", 10),
("SCM_BUTTONS", 25),
]

if CP.carFingerprint in (CAR.HONDA_CRV_HYBRID, CAR.HONDA_CIVIC_BOSCH_DIESEL, CAR.ACURA_RDX_3G, CAR.HONDA_E):
if CP.carFingerprint not in (CAR.ACURA_INTEGRA):
messages += [
("ENGINE_DATA", 100),
]
if CP.carFingerprint in (CAR.HONDA_CRV_HYBRID, CAR.HONDA_CIVIC_BOSCH_DIESEL, CAR.ACURA_RDX_3G, CAR.HONDA_E, CAR.ACURA_INTEGRA):
messages.append((gearbox_msg, 50))
else:
messages.append((gearbox_msg, 100))
Expand All @@ -65,7 +67,7 @@ def get_can_messages(CP, gearbox_msg):

# TODO: clean this up
if CP.carFingerprint in (CAR.HONDA_ACCORD, CAR.HONDA_CIVIC_BOSCH, CAR.HONDA_CIVIC_BOSCH_DIESEL, CAR.HONDA_CRV_HYBRID, CAR.HONDA_INSIGHT,
CAR.ACURA_RDX_3G, CAR.HONDA_E, CAR.HONDA_CIVIC_2022, CAR.HONDA_HRV_3G):
CAR.ACURA_RDX_3G, CAR.HONDA_E, CAR.HONDA_CIVIC_2022, CAR.HONDA_HRV_3G, CAR.ACURA_INTEGRA):
pass
elif CP.carFingerprint in (CAR.HONDA_ODYSSEY_CHN, CAR.HONDA_FREED, CAR.HONDA_HRV):
pass
Expand All @@ -87,12 +89,15 @@ def __init__(self, CP):
self.gearbox_msg = "GEARBOX"
if CP.carFingerprint == CAR.HONDA_ACCORD and CP.transmissionType == TransmissionType.cvt:
self.gearbox_msg = "GEARBOX_15T"
elif CP.transmissionType == TransmissionType.manual:
self.gearbox_msg = "GEARBOX_BOH"

self.main_on_sig_msg = "SCM_FEEDBACK"
if CP.carFingerprint in HONDA_NIDEC_ALT_SCM_MESSAGES:
self.main_on_sig_msg = "SCM_BUTTONS"

self.shifter_values = can_define.dv[self.gearbox_msg]["GEAR_SHIFTER"]
if CP.transmissionType != TransmissionType.manual:
self.shifter_values = can_define.dv[self.gearbox_msg]["GEAR_SHIFTER"]
self.steer_status_values = defaultdict(lambda: "UNKNOWN", can_define.dv["STEER_STATUS"]["STEER_STATUS"])

self.brake_switch_prev = False
Expand Down Expand Up @@ -123,10 +128,13 @@ def update(self, cp, cp_cam, cp_body):
# ******************* parse out can *******************
# STANDSTILL->WHEELS_MOVING bit can be noisy around zero, so use XMISSION_SPEED
# panda checks if the signal is non-zero
ret.standstill = cp.vl["ENGINE_DATA"]["XMISSION_SPEED"] < 1e-5
if self.CP.carFingerprint == CAR.ACURA_INTEGRA:
ret.standstill = cp.vl["CAR_SPEED"]["CAR_SPEED"] < 1e-5
else:
ret.standstill = cp.vl["ENGINE_DATA"]["XMISSION_SPEED"] < 1e-5
# TODO: find a common signal across all cars
if self.CP.carFingerprint in (CAR.HONDA_ACCORD, CAR.HONDA_CIVIC_BOSCH, CAR.HONDA_CIVIC_BOSCH_DIESEL, CAR.HONDA_CRV_HYBRID, CAR.HONDA_INSIGHT,
CAR.ACURA_RDX_3G, CAR.HONDA_E, CAR.HONDA_CIVIC_2022, CAR.HONDA_HRV_3G):
CAR.ACURA_RDX_3G, CAR.HONDA_E, CAR.HONDA_CIVIC_2022, CAR.HONDA_HRV_3G, CAR.ACURA_INTEGRA):
ret.doorOpen = bool(cp.vl["SCM_FEEDBACK"]["DRIVERS_DOOR_OPEN"])
elif self.CP.carFingerprint in (CAR.HONDA_ODYSSEY_CHN, CAR.HONDA_FREED, CAR.HONDA_HRV):
ret.doorOpen = bool(cp.vl["SCM_BUTTONS"]["DRIVERS_DOOR_OPEN"])
Expand Down Expand Up @@ -165,7 +173,10 @@ def update(self, cp, cp_cam, cp_body):

# blend in transmission speed at low speed, since it has more low speed accuracy
v_weight = interp(v_wheel, v_weight_bp, v_weight_v)
ret.vEgoRaw = (1. - v_weight) * cp.vl["ENGINE_DATA"]["XMISSION_SPEED"] * CV.KPH_TO_MS * self.CP.wheelSpeedFactor + v_weight * v_wheel
if self.CP.carFingerprint == CAR.ACURA_INTEGRA:
ret.vEgoRaw = (1. - v_weight) * cp.vl["CAR_SPEED"]["CAR_SPEED"] * CV.KPH_TO_MS * self.CP.wheelSpeedFactor + v_weight * v_wheel
else:
ret.vEgoRaw = (1. - v_weight) * cp.vl["ENGINE_DATA"]["XMISSION_SPEED"] * CV.KPH_TO_MS * self.CP.wheelSpeedFactor + v_weight * v_wheel
ret.vEgo, ret.aEgo = self.update_speed_kf(ret.vEgoRaw)

self.dash_speed_seen = self.dash_speed_seen or cp.vl["CAR_SPEED"]["ROUGH_CAR_SPEED_2"] > 1e-3
Expand All @@ -184,8 +195,16 @@ def update(self, cp, cp_cam, cp_body):
if self.CP.carFingerprint in (HONDA_BOSCH | {CAR.HONDA_CIVIC, CAR.HONDA_ODYSSEY, CAR.HONDA_ODYSSEY_CHN}):
ret.parkingBrake = cp.vl["EPB_STATUS"]["EPB_STATE"] != 0

gear = int(cp.vl[self.gearbox_msg]["GEAR_SHIFTER"])
ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(gear, None))
if self.CP.transmissionType == TransmissionType.manual:
ret.clutchPressed = cp.vl["GEARBOX_BOH"]["GEAR_MT"] == 0
if cp.vl["GEARBOX_BOH"]["GEAR_MT"] == 14:
ret.gearShifter = GearShifter.reverse
else:
ret.gearShifter = GearShifter.drive
else:
gear = int(cp.vl[self.gearbox_msg]["GEAR_SHIFTER"])
ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(gear, None))


ret.gas = cp.vl["POWERTRAIN_DATA"]["PEDAL_GAS"]
ret.gasPressed = ret.gas > 1e-5
Expand All @@ -200,6 +219,7 @@ def update(self, cp, cp_cam, cp_body):
ret.cruiseState.nonAdaptive = cp_cam.vl["ACC_HUD"]["CRUISE_CONTROL_LABEL"] != 0

if not self.CP.openpilotLongitudinalControl:
self.scm_buttons = cp.vl["SCM_BUTTONS"] if self.CP.carFingerprint in HONDA_BOSCH_RADARLESS else {}
# ACC_HUD is on camera bus on radarless cars
acc_hud = cp_cam.vl["ACC_HUD"] if self.CP.carFingerprint in HONDA_BOSCH_RADARLESS else cp.vl["ACC_HUD"]
ret.cruiseState.nonAdaptive = acc_hud["CRUISE_CONTROL_LABEL"] != 0
Expand Down
24 changes: 24 additions & 0 deletions selfdrive/car/honda/fingerprints.py
Original file line number Diff line number Diff line change
Expand Up @@ -1411,4 +1411,28 @@
b'37805-64S-AA10\x00\x00',
],
},
CAR.ACURA_INTEGRA: {
(Ecu.eps, 0x18da30f1, None): [
b'39990-T38-A040\x00\x00',
],
(Ecu.gateway, 0x18daeff1, None): [
b'38897-3S5-A110\x00\x00',
b'38897-3S5-A210\x00\x00',
],
(Ecu.srs, 0x18da53f1, None): [
b'77959-3S5-A920\x00\x00',
],
(Ecu.combinationMeter, 0x18da60f1, None): [
b'78108-3S5-AC20\x00\x00',
b'78108-3S5-A220\x00\x00',
],
(Ecu.vsa, 0x18da28f1, None): [
b'57114-3S5-CA30\x00\x00',
b'57114-3S5-CB30\x00\x00'
],
(Ecu.programmedFuelInjection, 0x18da10f1, None): [
b'37805-6LM-A020\x00\x00',
b'37805-6LM-A520\x00\x00',
],
},
}
15 changes: 11 additions & 4 deletions selfdrive/car/honda/hondacan.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,8 @@ def create_ui_commands(packer, CAN, CP, enabled, pcm_speed, hud, is_metric, acc_
commands.append(packer.make_can_msg("ACC_HUD", CAN.pt, acc_hud_values))

lkas_hud_values = {
'SET_ME_X41': 0x41,
'ENABLED': 1,
'SET_ME_X20': 0x20,
'STEERING_REQUIRED': hud.steer_required,
'SOLID_LANES': hud.lanes_visible,
'BEEP': 0,
Expand Down Expand Up @@ -201,11 +202,17 @@ def create_ui_commands(packer, CAN, CP, enabled, pcm_speed, hud, is_metric, acc_
return commands


def spam_buttons_command(packer, CAN, button_val, car_fingerprint):
def create_buttons_command(packer, CAN, button_val, setting_val, stock_scm_buttons, car_fingerprint):
values = {
'CRUISE_BUTTONS': button_val,
'CRUISE_SETTING': 0,
'CRUISE_BUTTONS': button_val
}
# Radarless: set CRUISE_SETTING & forward unmodified data bits
if len(stock_scm_buttons):
values.update({
'CRUISE_SETTING': setting_val,
'BOH_1': stock_scm_buttons['BOH_1'],
'BOH_2': stock_scm_buttons['BOH_2'],
})
# send buttons to camera on radarless cars
bus = CAN.camera if car_fingerprint in HONDA_BOSCH_RADARLESS else CAN.pt
return packer.make_can_msg("SCM_BUTTONS", bus, values)
5 changes: 4 additions & 1 deletion selfdrive/car/honda/interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
# Accord ICE 1.5T CVT has different gearbox message
if candidate == CAR.HONDA_ACCORD and 0x191 in fingerprint[CAN.pt]:
ret.transmissionType = TransmissionType.cvt
# Integra has MT option
elif candidate == CAR.ACURA_INTEGRA and 0x191 not in fingerprint[CAN.pt]:
ret.transmissionType = TransmissionType.manual

# Certain Hondas have an extra steering sensor at the bottom of the steering rack,
# which improves controls quality as it removes the steering column torsion from feedback.
Expand Down Expand Up @@ -103,7 +106,7 @@ def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 2560], [0, 2560]]
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[1.1], [0.33]]

elif candidate in (CAR.HONDA_CIVIC_BOSCH, CAR.HONDA_CIVIC_BOSCH_DIESEL, CAR.HONDA_CIVIC_2022):
elif candidate in (CAR.HONDA_CIVIC_BOSCH, CAR.HONDA_CIVIC_BOSCH_DIESEL, CAR.HONDA_CIVIC_2022, CAR.ACURA_INTEGRA):
ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.8], [0.24]]

Expand Down
12 changes: 12 additions & 0 deletions selfdrive/car/honda/values.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

Ecu = car.CarParams.Ecu
VisualAlert = car.CarControl.HUDControl.VisualAlert
GearShifter = car.CarState.GearShifter


class CarControllerParams:
Expand Down Expand Up @@ -66,6 +67,11 @@ class CruiseButtons:
DECEL_SET = 3
CANCEL = 2
MAIN = 1
NONE = 0

# CRUISE_SETTINGS
DISTANCE = 3
LKAS = 1


class CruiseSettings:
Expand Down Expand Up @@ -183,6 +189,12 @@ class CAR(Platforms):
CarSpecs(mass=3338.8 * CV.LB_TO_KG, wheelbase=2.5, centerToFrontRatio=0.5, steerRatio=16.71, tireStiffnessFactor=0.82),
dbc_dict('acura_rdx_2020_can_generated', None),
)
ACURA_INTEGRA = HondaBoschPlatformConfig(
[HondaCarDocs("Acura Integra 2024", "All")],
CarSpecs(mass=3338.8 * CV.LB_TO_KG, wheelbase=2.5, centerToFrontRatio=0.5, steerRatio=16.71, tireStiffnessFactor=0.82),
dbc_dict('honda_civic_ex_2022_can_generated', None),
flags=HondaFlags.BOSCH_RADARLESS,
)

# Nidec Cars
ACURA_ILX = HondaNidecPlatformConfig(
Expand Down
1 change: 1 addition & 0 deletions selfdrive/car/tests/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ class CarTestRoute(NamedTuple):
CarTestRoute("54fd8451b3974762|2021-04-01--14-50-10", HONDA.HONDA_RIDGELINE),
CarTestRoute("2d5808fae0b38ac6|2021-09-01--17-14-11", HONDA.HONDA_E),
CarTestRoute("f44aa96ace22f34a|2021-12-22--06-22-31", HONDA.HONDA_CIVIC_2022),
CarTestRoute("3f8ae015ce70365f/0000002b--d07abeff02", HONDA.ACURA_INTEGRA),

CarTestRoute("87d7f06ade479c2e|2023-09-11--23-30-11", HYUNDAI.HYUNDAI_AZERA_6TH_GEN),
CarTestRoute("66189dd8ec7b50e6|2023-09-20--07-02-12", HYUNDAI.HYUNDAI_AZERA_HEV_6TH_GEN),
Expand Down
1 change: 1 addition & 0 deletions selfdrive/car/torque_data/substitute.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"]
"HONDA_CIVIC_BOSCH_DIESEL" = "HONDA_CIVIC_BOSCH"
"HONDA_E" = "HONDA_CIVIC_BOSCH"
"HONDA_ODYSSEY_CHN" = "HONDA_ODYSSEY"
"ACURA_INTEGRA" = "HONDA_CIVIC_2022"

"BUICK_LACROSSE" = "CHEVROLET_VOLT"
"BUICK_REGAL" = "CHEVROLET_VOLT"
Expand Down
Loading