from dataclasses import dataclass
from enum import Enum , IntFlag
from cereal import car
from panda . python import uds
from openpilot . selfdrive . car import CarSpecs , PlatformConfig , Platforms , dbc_dict
from openpilot . selfdrive . car . conversions import Conversions as CV
from openpilot . selfdrive . car . docs_definitions import CarFootnote , CarHarness , CarDocs , CarParts , Column
from openpilot . selfdrive . car . fw_query_definitions import FwQueryConfig , Request , StdQueries , p16
Ecu = car . CarParams . Ecu
VisualAlert = car . CarControl . HUDControl . VisualAlert
class CarControllerParams :
# Allow small margin below -3.5 m/s^2 from ISO 15622:2018 since we
# perform the closed loop control, and might need some
# to apply some more braking if we're on a downhill slope.
# Our controller should still keep the 2 second average above
# -3.5 m/s^2 as per planner limits
NIDEC_ACCEL_MIN = - 4.0 # m/s^2
NIDEC_ACCEL_MAX = 1.6 # m/s^2, lower than 2.0 m/s^2 for tuning reasons
NIDEC_ACCEL_LOOKUP_BP = [ - 1. , 0. , .6 ]
NIDEC_ACCEL_LOOKUP_V = [ - 4.8 , 0. , 2.0 ]
NIDEC_MAX_ACCEL_V = [ 0.5 , 2.4 , 1.4 , 0.6 ]
NIDEC_MAX_ACCEL_BP = [ 0.0 , 4.0 , 10. , 20. ]
NIDEC_GAS_MAX = 198 # 0xc6
NIDEC_BRAKE_MAX = 1024 / / 4
BOSCH_ACCEL_MIN = - 3.5 # m/s^2
BOSCH_ACCEL_MAX = 2.0 # m/s^2
BOSCH_GAS_LOOKUP_BP = [ - 0.2 , 2.0 ] # 2m/s^2
BOSCH_GAS_LOOKUP_V = [ 0 , 1600 ]
def __init__ ( self , CP ) :
self . STEER_MAX = CP . lateralParams . torqueBP [ - 1 ]
# mirror of list (assuming first item is zero) for interp of signed request values
assert ( CP . lateralParams . torqueBP [ 0 ] == 0 )
assert ( CP . lateralParams . torqueBP [ 0 ] == 0 )
self . STEER_LOOKUP_BP = [ v * - 1 for v in CP . lateralParams . torqueBP ] [ 1 : ] [ : : - 1 ] + list ( CP . lateralParams . torqueBP )
self . STEER_LOOKUP_V = [ v * - 1 for v in CP . lateralParams . torqueV ] [ 1 : ] [ : : - 1 ] + list ( CP . lateralParams . torqueV )
class HondaFlags ( IntFlag ) :
# Detected flags
# Bosch models with alternate set of LKAS_HUD messages
BOSCH_EXT_HUD = 1
BOSCH_ALT_BRAKE = 2
# Static flags
BOSCH = 4
BOSCH_RADARLESS = 8
NIDEC = 16
NIDEC_ALT_PCM_ACCEL = 32
NIDEC_ALT_SCM_MESSAGES = 64
# Car button codes
class CruiseButtons :
RES_ACCEL = 4
DECEL_SET = 3
CANCEL = 2
MAIN = 1
class CruiseSettings :
DISTANCE = 3
LKAS = 1
# See dbc files for info on values
VISUAL_HUD = {
VisualAlert . none : 0 ,
VisualAlert . fcw : 1 ,
VisualAlert . steerRequired : 1 ,
VisualAlert . ldw : 1 ,
VisualAlert . brakePressed : 10 ,
VisualAlert . wrongGear : 6 ,
VisualAlert . seatbeltUnbuckled : 5 ,
VisualAlert . speedTooHigh : 8
}
@dataclass
class HondaCarDocs ( CarDocs ) :
package : str = " Honda Sensing "
def init_make ( self , CP : car . CarParams ) :
if CP . flags & HondaFlags . BOSCH :
self . car_parts = CarParts . common ( [ CarHarness . bosch_b ] ) if CP . flags & HondaFlags . BOSCH_RADARLESS else CarParts . common ( [ CarHarness . bosch_a ] )
else :
self . car_parts = CarParts . common ( [ CarHarness . nidec ] )
class Footnote ( Enum ) :
CIVIC_DIESEL = CarFootnote (
" 2019 Honda Civic 1.6L Diesel Sedan does not have ALC below 12mph. " ,
Column . FSR_STEERING )
class HondaBoschPlatformConfig ( PlatformConfig ) :
def init ( self ) :
self . flags | = HondaFlags . BOSCH
class HondaNidecPlatformConfig ( PlatformConfig ) :
def init ( self ) :
self . flags | = HondaFlags . NIDEC
class CAR ( Platforms ) :
# Bosch Cars
HONDA_ACCORD = HondaBoschPlatformConfig (
[
HondaCarDocs ( " Honda Accord 2018-22 " , " All " , video_link = " https://www.youtube.com/watch?v=mrUwlj3Mi58 " , min_steer_speed = 3. * CV . MPH_TO_MS ) ,
HondaCarDocs ( " Honda Inspire 2018 " , " All " , min_steer_speed = 3. * CV . MPH_TO_MS ) ,
HondaCarDocs ( " Honda Accord Hybrid 2018-22 " , " All " , min_steer_speed = 3. * CV . MPH_TO_MS ) ,
] ,
# steerRatio: 11.82 is spec end-to-end
CarSpecs ( mass = 3279 * CV . LB_TO_KG , wheelbase = 2.83 , steerRatio = 16.33 , centerToFrontRatio = 0.39 , tireStiffnessFactor = 0.8467 ) ,
dbc_dict ( ' honda_accord_2018_can_generated ' , None ) ,
)
HONDA_CIVIC_BOSCH = HondaBoschPlatformConfig (
[
HondaCarDocs ( " Honda Civic 2019-21 " , " All " , video_link = " https://www.youtube.com/watch?v=4Iz1Mz5LGF8 " ,
footnotes = [ Footnote . CIVIC_DIESEL ] , min_steer_speed = 2. * CV . MPH_TO_MS ) ,
HondaCarDocs ( " Honda Civic Hatchback 2017-21 " , min_steer_speed = 12. * CV . MPH_TO_MS ) ,
] ,
CarSpecs ( mass = 1326 , wheelbase = 2.7 , steerRatio = 15.38 , centerToFrontRatio = 0.4 ) , # steerRatio: 10.93 is end-to-end spec
dbc_dict ( ' honda_civic_hatchback_ex_2017_can_generated ' , None ) ,
)
HONDA_CIVIC_BOSCH_DIESEL = HondaBoschPlatformConfig (
[ ] , # don't show in docs
HONDA_CIVIC_BOSCH . specs ,
dbc_dict ( ' honda_accord_2018_can_generated ' , None ) ,
)
HONDA_CIVIC_2022 = HondaBoschPlatformConfig (
[
HondaCarDocs ( " Honda Civic 2022-24 " , " All " , video_link = " https://youtu.be/ytiOT5lcp6Q " ) ,
HondaCarDocs ( " Honda Civic Hatchback 2022-24 " , " All " , video_link = " https://youtu.be/ytiOT5lcp6Q " ) ,
] ,
HONDA_CIVIC_BOSCH . specs ,
dbc_dict ( ' honda_civic_ex_2022_can_generated ' , None ) ,
flags = HondaFlags . BOSCH_RADARLESS ,
)
HONDA_CRV_5G = HondaBoschPlatformConfig (
[ HondaCarDocs ( " Honda CR-V 2017-22 " , min_steer_speed = 12. * CV . MPH_TO_MS ) ] ,
# steerRatio: 12.3 is spec end-to-end
CarSpecs ( mass = 3410 * CV . LB_TO_KG , wheelbase = 2.66 , steerRatio = 16.0 , centerToFrontRatio = 0.41 , tireStiffnessFactor = 0.677 ) ,
dbc_dict ( ' honda_crv_ex_2017_can_generated ' , None , body_dbc = ' honda_crv_ex_2017_body_generated ' ) ,
flags = HondaFlags . BOSCH_ALT_BRAKE ,
)
HONDA_CRV_HYBRID = HondaBoschPlatformConfig (
[ HondaCarDocs ( " Honda CR-V Hybrid 2017-21 " , min_steer_speed = 12. * CV . MPH_TO_MS ) ] ,
# mass: mean of 4 models in kg, steerRatio: 12.3 is spec end-to-end
CarSpecs ( mass = 1667 , wheelbase = 2.66 , steerRatio = 16 , centerToFrontRatio = 0.41 , tireStiffnessFactor = 0.677 ) ,
dbc_dict ( ' honda_accord_2018_can_generated ' , None ) ,
)
HONDA_HRV_3G = HondaBoschPlatformConfig (
[ HondaCarDocs ( " Honda HR-V 2023 " , " All " ) ] ,
CarSpecs ( mass = 3125 * CV . LB_TO_KG , wheelbase = 2.61 , steerRatio = 15.2 , centerToFrontRatio = 0.41 , tireStiffnessFactor = 0.5 ) ,
dbc_dict ( ' honda_civic_ex_2022_can_generated ' , None ) ,
flags = HondaFlags . BOSCH_RADARLESS ,
)
ACURA_RDX_3G = HondaBoschPlatformConfig (
[ HondaCarDocs ( " Acura RDX 2019-22 " , " All " , min_steer_speed = 3. * CV . MPH_TO_MS ) ] ,
CarSpecs ( mass = 4068 * CV . LB_TO_KG , wheelbase = 2.75 , steerRatio = 11.95 , centerToFrontRatio = 0.41 , tireStiffnessFactor = 0.677 ) , # as spec
dbc_dict ( ' acura_rdx_2020_can_generated ' , None ) ,
flags = HondaFlags . BOSCH_ALT_BRAKE ,
)
HONDA_INSIGHT = HondaBoschPlatformConfig (
[ HondaCarDocs ( " Honda Insight 2019-22 " , " All " , min_steer_speed = 3. * CV . MPH_TO_MS ) ] ,
CarSpecs ( mass = 2987 * CV . LB_TO_KG , wheelbase = 2.7 , steerRatio = 15.0 , centerToFrontRatio = 0.39 , tireStiffnessFactor = 0.82 ) , # as spec
dbc_dict ( ' honda_insight_ex_2019_can_generated ' , None ) ,
)
HONDA_E = HondaBoschPlatformConfig (
[ HondaCarDocs ( " Honda e 2020 " , " All " , min_steer_speed = 3. * CV . MPH_TO_MS ) ] ,
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 ) ,
)
# Nidec Cars
ACURA_ILX = HondaNidecPlatformConfig (
[ HondaCarDocs ( " Acura ILX 2016-19 " , " AcuraWatch Plus " , min_steer_speed = 25. * CV . MPH_TO_MS ) ] ,
CarSpecs ( mass = 3095 * CV . LB_TO_KG , wheelbase = 2.67 , steerRatio = 18.61 , centerToFrontRatio = 0.37 , tireStiffnessFactor = 0.72 ) , # 15.3 is spec end-to-end
dbc_dict ( ' acura_ilx_2016_can_generated ' , ' acura_ilx_2016_nidec ' ) ,
flags = HondaFlags . NIDEC_ALT_SCM_MESSAGES ,
)
HONDA_CRV = HondaNidecPlatformConfig (
[ HondaCarDocs ( " Honda CR-V 2015-16 " , " Touring Trim " , min_steer_speed = 12. * CV . MPH_TO_MS ) ] ,
CarSpecs ( mass = 3572 * CV . LB_TO_KG , wheelbase = 2.62 , steerRatio = 16.89 , centerToFrontRatio = 0.41 , tireStiffnessFactor = 0.444 ) , # as spec
dbc_dict ( ' honda_crv_touring_2016_can_generated ' , ' acura_ilx_2016_nidec ' ) ,
flags = HondaFlags . NIDEC_ALT_SCM_MESSAGES ,
)
HONDA_CRV_EU = HondaNidecPlatformConfig (
[ ] , # Euro version of CRV Touring, don't show in docs
HONDA_CRV . specs ,
dbc_dict ( ' honda_crv_executive_2016_can_generated ' , ' acura_ilx_2016_nidec ' ) ,
flags = HondaFlags . NIDEC_ALT_SCM_MESSAGES ,
)
HONDA_FIT = HondaNidecPlatformConfig (
[ HondaCarDocs ( " Honda Fit 2018-20 " , min_steer_speed = 12. * CV . MPH_TO_MS ) ] ,
CarSpecs ( mass = 2644 * CV . LB_TO_KG , wheelbase = 2.53 , steerRatio = 13.06 , centerToFrontRatio = 0.39 , tireStiffnessFactor = 0.75 ) ,
dbc_dict ( ' honda_fit_ex_2018_can_generated ' , ' acura_ilx_2016_nidec ' ) ,
flags = HondaFlags . NIDEC_ALT_SCM_MESSAGES ,
)
HONDA_FREED = HondaNidecPlatformConfig (
[ HondaCarDocs ( " Honda Freed 2020 " , min_steer_speed = 12. * CV . MPH_TO_MS ) ] ,
CarSpecs ( mass = 3086. * CV . LB_TO_KG , wheelbase = 2.74 , steerRatio = 13.06 , centerToFrontRatio = 0.39 , tireStiffnessFactor = 0.75 ) , # mostly copied from FIT
dbc_dict ( ' honda_fit_ex_2018_can_generated ' , ' acura_ilx_2016_nidec ' ) ,
flags = HondaFlags . NIDEC_ALT_SCM_MESSAGES ,
)
HONDA_HRV = HondaNidecPlatformConfig (
[ HondaCarDocs ( " Honda HR-V 2019-22 " , min_steer_speed = 12. * CV . MPH_TO_MS ) ] ,
HONDA_HRV_3G . specs ,
dbc_dict ( ' honda_fit_ex_2018_can_generated ' , ' acura_ilx_2016_nidec ' ) ,
flags = HondaFlags . NIDEC_ALT_SCM_MESSAGES ,
)
HONDA_ODYSSEY = HondaNidecPlatformConfig (
[ HondaCarDocs ( " Honda Odyssey 2018-20 " ) ] ,
CarSpecs ( mass = 1900 , wheelbase = 3.0 , steerRatio = 14.35 , centerToFrontRatio = 0.41 , tireStiffnessFactor = 0.82 ) ,
dbc_dict ( ' honda_odyssey_exl_2018_generated ' , ' acura_ilx_2016_nidec ' ) ,
flags = HondaFlags . NIDEC_ALT_PCM_ACCEL ,
)
HONDA_ODYSSEY_CHN = HondaNidecPlatformConfig (
[ ] , # Chinese version of Odyssey, don't show in docs
HONDA_ODYSSEY . specs ,
dbc_dict ( ' honda_odyssey_extreme_edition_2018_china_can_generated ' , ' acura_ilx_2016_nidec ' ) ,
flags = HondaFlags . NIDEC_ALT_SCM_MESSAGES ,
)
ACURA_RDX = HondaNidecPlatformConfig (
[ HondaCarDocs ( " Acura RDX 2016-18 " , " AcuraWatch Plus " , min_steer_speed = 12. * CV . MPH_TO_MS ) ] ,
CarSpecs ( mass = 3925 * CV . LB_TO_KG , wheelbase = 2.68 , steerRatio = 15.0 , centerToFrontRatio = 0.38 , tireStiffnessFactor = 0.444 ) , # as spec
dbc_dict ( ' acura_rdx_2018_can_generated ' , ' acura_ilx_2016_nidec ' ) ,
flags = HondaFlags . NIDEC_ALT_SCM_MESSAGES ,
)
HONDA_PILOT = HondaNidecPlatformConfig (
[
HondaCarDocs ( " Honda Pilot 2016-22 " , min_steer_speed = 12. * CV . MPH_TO_MS ) ,
HondaCarDocs ( " Honda Passport 2019-23 " , " All " , min_steer_speed = 12. * CV . MPH_TO_MS ) ,
] ,
CarSpecs ( mass = 4278 * CV . LB_TO_KG , wheelbase = 2.86 , centerToFrontRatio = 0.428 , steerRatio = 16.0 , tireStiffnessFactor = 0.444 ) , # as spec
dbc_dict ( ' acura_ilx_2016_can_generated ' , ' acura_ilx_2016_nidec ' ) ,
flags = HondaFlags . NIDEC_ALT_SCM_MESSAGES ,
)
HONDA_RIDGELINE = HondaNidecPlatformConfig (
[ HondaCarDocs ( " Honda Ridgeline 2017-24 " , min_steer_speed = 12. * CV . MPH_TO_MS ) ] ,
CarSpecs ( mass = 4515 * CV . LB_TO_KG , wheelbase = 3.18 , centerToFrontRatio = 0.41 , steerRatio = 15.59 , tireStiffnessFactor = 0.444 ) , # as spec
dbc_dict ( ' acura_ilx_2016_can_generated ' , ' acura_ilx_2016_nidec ' ) ,
flags = HondaFlags . NIDEC_ALT_SCM_MESSAGES ,
)
HONDA_CIVIC = HondaNidecPlatformConfig (
[ HondaCarDocs ( " Honda Civic 2016-18 " , min_steer_speed = 12. * CV . MPH_TO_MS , video_link = " https://youtu.be/-IkImTe1NYE " ) ] ,
CarSpecs ( mass = 1326 , wheelbase = 2.70 , centerToFrontRatio = 0.4 , steerRatio = 15.38 ) , # 10.93 is end-to-end spec
dbc_dict ( ' honda_civic_touring_2016_can_generated ' , ' acura_ilx_2016_nidec ' ) ,
)
HONDA_ALT_VERSION_REQUEST = bytes ( [ uds . SERVICE_TYPE . READ_DATA_BY_IDENTIFIER ] ) + \
p16 ( 0xF112 )
HONDA_ALT_VERSION_RESPONSE = bytes ( [ uds . SERVICE_TYPE . READ_DATA_BY_IDENTIFIER + 0x40 ] ) + \
p16 ( 0xF112 )
FW_QUERY_CONFIG = FwQueryConfig (
requests = [
# Currently used to fingerprint
Request (
[ StdQueries . UDS_VERSION_REQUEST ] ,
[ StdQueries . UDS_VERSION_RESPONSE ] ,
bus = 1 ,
) ,
# Data collection requests:
# Log manufacturer-specific identifier for current ECUs
Request (
[ HONDA_ALT_VERSION_REQUEST ] ,
[ HONDA_ALT_VERSION_RESPONSE ] ,
bus = 1 ,
logging = True ,
) ,
# Nidec PT bus
Request (
[ StdQueries . UDS_VERSION_REQUEST ] ,
[ StdQueries . UDS_VERSION_RESPONSE ] ,
bus = 0 ,
) ,
# Bosch PT bus
Request (
[ StdQueries . UDS_VERSION_REQUEST ] ,
[ StdQueries . UDS_VERSION_RESPONSE ] ,
bus = 1 ,
obd_multiplexing = False ,
) ,
] ,
# We lose these ECUs without the comma power on these cars.
# Note that we still attempt to match with them when they are present
# This is or'd with (ALL_ECUS - ESSENTIAL_ECUS) from fw_versions.py
non_essential_ecus = {
Ecu . eps : [ CAR . ACURA_RDX_3G , CAR . HONDA_ACCORD , CAR . HONDA_CIVIC_2022 , CAR . HONDA_E , CAR . HONDA_HRV_3G ] ,
Ecu . vsa : [ CAR . ACURA_RDX_3G , CAR . HONDA_ACCORD , CAR . HONDA_CIVIC , CAR . HONDA_CIVIC_BOSCH , CAR . HONDA_CIVIC_2022 , CAR . HONDA_CRV_5G , CAR . HONDA_CRV_HYBRID ,
CAR . HONDA_E , CAR . HONDA_HRV_3G , CAR . HONDA_INSIGHT ] ,
} ,
extra_ecus = [
( Ecu . combinationMeter , 0x18da60f1 , None ) ,
( Ecu . programmedFuelInjection , 0x18da10f1 , None ) ,
# The only other ECU on PT bus accessible by camera on radarless Civic
# This is likely a manufacturer-specific sub-address implementation: the camera responds to this and 0x18dab0f1
# Unclear what the part number refers to: 8S103 is 'Camera Set Mono', while 36160 is 'Camera Monocular - Honda'
# TODO: add query back, camera does not support querying both in parallel and 0x18dab0f1 often fails to respond
# (Ecu.unknown, 0x18DAB3F1, None),
] ,
)
STEER_THRESHOLD = {
# default is 1200, overrides go here
CAR . ACURA_RDX : 400 ,
CAR . HONDA_CRV_EU : 400 ,
}
HONDA_NIDEC_ALT_PCM_ACCEL = CAR . with_flags ( HondaFlags . NIDEC_ALT_PCM_ACCEL )
HONDA_NIDEC_ALT_SCM_MESSAGES = CAR . with_flags ( HondaFlags . NIDEC_ALT_SCM_MESSAGES )
HONDA_BOSCH = CAR . with_flags ( HondaFlags . BOSCH )
HONDA_BOSCH_RADARLESS = CAR . with_flags ( HondaFlags . BOSCH_RADARLESS )
DBC = CAR . create_dbc_map ( )