Bounty: Mazda (#988)
	
		
	
				
					
				
			* Mazda Port Signed-off-by: Jafar Al-Gharaibeh <to.jafar@gmail.com> * Update checksum to account for steer angle signal used in some cars Signed-off-by: Jafar Al-Gharaibeh <to.jafar@gmail.com> * Add test drive/segment ID to pass CI tests Signed-off-by: Jafar Al-Gharaibeh <to.jafar@gmail.com> * Process gear and brake signals, add new fingerprints Signed-off-by: Jafar Al-Gharaibeh <to.jafar@gmail.com> * Refactor some car interface code Signed-off-by: Jafar Al-Gharaibeh <to.jafar@gmail.com> * Drop redundant call, use Ecu, move warning to carstate, fix cruise speed Signed-off-by: Jafar Al-Gharaibeh <to.jafar@gmail.com> * Drop unused variables, cleanup handsoff tracking Signed-off-by: Jafar Al-Gharaibeh <to.jafar@gmail.com> * Update to steerError and steeringRate Signed-off-by: Jafar Al-Gharaibeh <to.jafar@gmail.com> * Refactor parse gear, update lkas signals from the new dbc Signed-off-by: Jafar Al-Gharaibeh <to.jafar@gmail.com> * Better tracking of engage and warning events Signed-off-by: Jafar Al-Gharaibeh <to.jafar@gmail.com> * remove commented lines, update speed_kph to match panda Signed-off-by: Jafar Al-Gharaibeh <to.jafar@gmail.com> * Steer Error Signed-off-by: Jafar Al-Gharaibeh <to.jafar@gmail.com> * Set lkas enable speed to 52 kph Signed-off-by: Jafar Al-Gharaibeh <to.jafar@gmail.com> * Drop block signal use, fix LGTM alerts Signed-off-by: Jafar Al-Gharaibeh <to.jafar@gmail.com> * When gas is pressed OP will disengage, sync local state with it Signed-off-by: Jafar Al-Gharaibeh <to.jafar@gmail.com> * Use car's speed signal instead of wheel speed Signed-off-by: Jafar Al-Gharaibeh <to.jafar@gmail.com> * Tidy up disengage events Signed-off-by: Jafar Al-Gharaibeh <to.jafar@gmail.com> * Rebase/Refactor with upstream Signed-off-by: Jafar Al-Gharaibeh <to.jafar@gmail.com> * Sync stock ACC state with OP Signed-off-by: Jafar Al-Gharaibeh <to.jafar@gmail.com> * mazda dbc file renamed Signed-off-by: Jafar Al-Gharaibeh <to.jafar@gmail.com> * Improve acc stock and go by removing the 3 seconds limit Signed-off-by: Jafar Al-Gharaibeh <to.jafar@gmail.com> * Dashcam Signed-off-by: Jafar Al-Gharaibeh <to.jafar@gmail.com> * PR Feedback Signed-off-by: Jafar Al-Gharaibeh <to.jafar@gmail.com> * Send ACC cancel only if we are sure cruise is enabled Otherwise we run the risk of disabling main cruise Signed-off-by: Jafar Al-Gharaibeh <to.jafar@gmail.com> * updated route Signed-off-by: Jafar Al-Gharaibeh <to.jafar@gmail.com> * no process replay for now * add to release files * Revert "updated route" This reverts commitcommatwo_master233db4f1bc. Co-authored-by: Adeeb Shihadeh <adeebshihadeh@gmail.com> old-commit-hash:34b9b5e849
							parent
							
								
									5ab1d48f90
								
							
						
					
					
						commit
						a476d51333
					
				
				 10 changed files with 515 additions and 2 deletions
			
			
		| @ -0,0 +1 @@ | ||||
| 
 | ||||
| @ -0,0 +1,44 @@ | ||||
| from selfdrive.car.mazda import mazdacan | ||||
| from selfdrive.car.mazda.values import SteerLimitParams, Buttons | ||||
| from opendbc.can.packer import CANPacker | ||||
| from selfdrive.car import apply_std_steer_torque_limits | ||||
| 
 | ||||
| class CarController(): | ||||
|   def __init__(self, dbc_name, CP, VM): | ||||
|     self.apply_steer_last = 0 | ||||
|     self.packer = CANPacker(dbc_name) | ||||
|     self.steer_rate_limited = False | ||||
| 
 | ||||
|   def update(self, enabled, CS, frame, actuators): | ||||
|     """ Controls thread """ | ||||
| 
 | ||||
|     can_sends = [] | ||||
| 
 | ||||
|     ### STEER ### | ||||
| 
 | ||||
|     if enabled: | ||||
|       # calculate steer and also set limits due to driver torque | ||||
|       new_steer = int(round(actuators.steer * SteerLimitParams.STEER_MAX)) | ||||
|       apply_steer = apply_std_steer_torque_limits(new_steer, self.apply_steer_last, | ||||
|                                                   CS.out.steeringTorque, SteerLimitParams) | ||||
|       self.steer_rate_limited = new_steer != apply_steer | ||||
| 
 | ||||
|       if CS.out.standstill and frame % 50 == 0: | ||||
|         # Mazda Stop and Go requires a RES button (or gas) press if the car stops more than 3 seconds | ||||
|         # Send Resume button at 2hz if we're engaged at standstill to support full stop and go! | ||||
|         # TODO: improve the resume trigger logic by looking at actual radar data | ||||
|         can_sends.append(mazdacan.create_button_cmd(self.packer, CS.CP.carFingerprint, Buttons.RESUME)) | ||||
|     else: | ||||
|       apply_steer = 0 | ||||
|       self.steer_rate_limited = False | ||||
|       if CS.out.cruiseState.enabled and frame % 10 == 0: | ||||
|         # Cancel Stock ACC if it's enabled while OP is disengaged | ||||
|         # Match stock message rate which is sent at 10hz | ||||
|         can_sends.append(mazdacan.create_button_cmd(self.packer, CS.CP.carFingerprint, Buttons.CANCEL)) | ||||
| 
 | ||||
| 
 | ||||
|     self.apply_steer_last = apply_steer | ||||
|    | ||||
|     can_sends.append(mazdacan.create_steering_control(self.packer, CS.CP.carFingerprint, | ||||
|                                                       frame, apply_steer, CS.cam_lkas)) | ||||
|     return can_sends | ||||
| @ -0,0 +1,185 @@ | ||||
| from cereal import car | ||||
| from selfdrive.config import Conversions as CV | ||||
| from opendbc.can.can_define import CANDefine | ||||
| from opendbc.can.parser import CANParser | ||||
| from selfdrive.car.interfaces import CarStateBase | ||||
| from selfdrive.car.mazda.values import DBC, LKAS_LIMITS, CAR | ||||
| 
 | ||||
| class CarState(CarStateBase): | ||||
|   def __init__(self, CP): | ||||
|     super().__init__(CP) | ||||
| 
 | ||||
|     can_define = CANDefine(DBC[CP.carFingerprint]['pt']) | ||||
|     self.shifter_values = can_define.dv["GEAR"]['GEAR'] | ||||
| 
 | ||||
|     self.cruise_speed = 0 | ||||
|     self.acc_active_last = False | ||||
|     self.low_speed_lockout = True | ||||
|     self.low_speed_alert = False | ||||
|     self.lkas_allowed = False | ||||
| 
 | ||||
|   def update(self, cp, cp_cam): | ||||
| 
 | ||||
|     ret = car.CarState.new_message() | ||||
|     ret.wheelSpeeds.fl = cp.vl["WHEEL_SPEEDS"]['FL'] * CV.KPH_TO_MS | ||||
|     ret.wheelSpeeds.fr = cp.vl["WHEEL_SPEEDS"]['FR'] * CV.KPH_TO_MS | ||||
|     ret.wheelSpeeds.rl = cp.vl["WHEEL_SPEEDS"]['RL'] * CV.KPH_TO_MS | ||||
|     ret.wheelSpeeds.rr = cp.vl["WHEEL_SPEEDS"]['RR'] * CV.KPH_TO_MS | ||||
|     ret.vEgoRaw = (ret.wheelSpeeds.fl + ret.wheelSpeeds.fr + ret.wheelSpeeds.rl + ret.wheelSpeeds.rr) / 4. | ||||
|     ret.vEgo, ret.aEgo = self.update_speed_kf(ret.vEgoRaw) | ||||
| 
 | ||||
|     # Match panda speed reading | ||||
|     speed_kph = cp.vl["ENGINE_DATA"]['SPEED'] | ||||
|     ret.standstill = speed_kph < .1 | ||||
| 
 | ||||
|     can_gear = int(cp.vl["GEAR"]['GEAR']) | ||||
|     ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(can_gear, None)) | ||||
| 
 | ||||
|     ret.leftBlinker = cp.vl["BLINK_INFO"]['LEFT_BLINK'] == 1 | ||||
|     ret.rightBlinker = cp.vl["BLINK_INFO"]['RIGHT_BLINK'] == 1 | ||||
| 
 | ||||
|     ret.steeringAngle =  cp.vl["STEER"]['STEER_ANGLE'] | ||||
|     ret.steeringTorque = cp.vl["STEER_TORQUE"]['STEER_TORQUE_SENSOR'] | ||||
|     ret.steeringPressed = abs(ret.steeringTorque) > LKAS_LIMITS.STEER_THRESHOLD | ||||
| 
 | ||||
|     ret.steeringTorqueEps = cp.vl["STEER_TORQUE"]['STEER_TORQUE_MOTOR'] | ||||
|     ret.steeringRate = cp.vl["STEER_RATE"]['STEER_ANGLE_RATE'] | ||||
| 
 | ||||
|     ret.brakePressed = cp.vl["PEDALS"]['BRAKE_ON'] == 1 | ||||
|     ret.brake = cp.vl["BRAKE"]['BRAKE_PRESSURE'] | ||||
|     ret.brakeLights = ret.brakePressed | ||||
| 
 | ||||
|     ret.seatbeltUnlatched = cp.vl["SEATBELT"]['DRIVER_SEATBELT'] == 0 | ||||
|     ret.doorOpen = any([cp.vl["DOORS"]['FL'], cp.vl["DOORS"]['FR'], | ||||
|                         cp.vl["DOORS"]['BL'], cp.vl["DOORS"]['BR']]) | ||||
| 
 | ||||
|     ret.gas = cp.vl["ENGINE_DATA"]['PEDAL_GAS'] | ||||
|     ret.gasPressed = ret.gas > 0 | ||||
| 
 | ||||
| 
 | ||||
|     # LKAS is enabled at 52kph going up and disabled at 45kph going down | ||||
|     if speed_kph > LKAS_LIMITS.ENABLE_SPEED: | ||||
|       self.lkas_allowed = True | ||||
|     elif speed_kph < LKAS_LIMITS.DISABLE_SPEED: | ||||
|       self.lkas_allowed = False | ||||
| 
 | ||||
|     # if any of the cruize buttons is pressed force state update | ||||
|     if any([cp.vl["CRZ_BTNS"]['RES'], | ||||
|                 cp.vl["CRZ_BTNS"]['SET_P'], | ||||
|                 cp.vl["CRZ_BTNS"]['SET_M']]): | ||||
|       self.cruise_speed = ret.vEgoRaw | ||||
| 
 | ||||
|     ret.cruiseState.available = True | ||||
|     ret.cruiseState.enabled =  cp.vl["CRZ_CTRL"]['CRZ_ACTIVE'] == 1 | ||||
|     ret.cruiseState.speed = self.cruise_speed | ||||
| 
 | ||||
|     if ret.cruiseState.enabled: | ||||
|       if not self.lkas_allowed: | ||||
|         if not self.acc_active_last: | ||||
|           self.low_speed_lockout = True | ||||
|         else: | ||||
|           self.low_speed_alert = True | ||||
|       else: | ||||
|         self.low_speed_lockout = False | ||||
|         self.low_speed_alert = False | ||||
| 
 | ||||
|     # On if no driver torque the last 5 seconds | ||||
|     ret.steerWarning = cp.vl["STEER_RATE"]['HANDS_OFF_5_SECONDS'] == 1 | ||||
| 
 | ||||
|     self.acc_active_last = ret.cruiseState.enabled | ||||
| 
 | ||||
|     self.cam_lkas = cp_cam.vl["CAM_LKAS"] | ||||
|     ret.steerError = cp_cam.vl["CAM_LKAS"]['ERR_BIT_1'] == 1 | ||||
| 
 | ||||
|     return ret | ||||
| 
 | ||||
|   @staticmethod | ||||
|   def get_can_parser(CP): | ||||
|     # this function generates lists for signal, messages and initial values | ||||
|     signals = [ | ||||
|       # sig_name, sig_address, default | ||||
|       ("LEFT_BLINK", "BLINK_INFO", 0), | ||||
|       ("RIGHT_BLINK", "BLINK_INFO", 0), | ||||
|       ("STEER_ANGLE", "STEER", 0), | ||||
|       ("STEER_ANGLE_RATE", "STEER_RATE", 0), | ||||
|       ("STEER_TORQUE_SENSOR", "STEER_TORQUE", 0), | ||||
|       ("STEER_TORQUE_MOTOR", "STEER_TORQUE", 0), | ||||
|       ("FL", "WHEEL_SPEEDS", 0), | ||||
|       ("FR", "WHEEL_SPEEDS", 0), | ||||
|       ("RL", "WHEEL_SPEEDS", 0), | ||||
|       ("RR", "WHEEL_SPEEDS", 0), | ||||
|     ] | ||||
| 
 | ||||
|     checks = [ | ||||
|       # sig_address, frequency | ||||
|       ("BLINK_INFO", 10), | ||||
|       ("STEER", 67), | ||||
|       ("STEER_RATE", 83), | ||||
|       ("STEER_TORQUE", 83), | ||||
|       ("WHEEL_SPEEDS", 100), | ||||
|     ] | ||||
| 
 | ||||
|     if CP.carFingerprint == CAR.CX5: | ||||
|       signals += [ | ||||
|         ("LKAS_BLOCK", "STEER_RATE", 0), | ||||
|         ("LKAS_TRACK_STATE", "STEER_RATE", 0), | ||||
|         ("HANDS_OFF_5_SECONDS", "STEER_RATE", 0), | ||||
|         ("CRZ_ACTIVE", "CRZ_CTRL", 0), | ||||
|         ("STANDSTILL","PEDALS", 0), | ||||
|         ("BRAKE_ON","PEDALS", 0), | ||||
|         ("BRAKE_PRESSURE","BRAKE", 0), | ||||
|         ("GEAR","GEAR", 0), | ||||
|         ("DRIVER_SEATBELT", "SEATBELT", 0), | ||||
|         ("FL", "DOORS", 0), | ||||
|         ("FR", "DOORS", 0), | ||||
|         ("BL", "DOORS", 0), | ||||
|         ("BR", "DOORS", 0), | ||||
|         ("PEDAL_GAS", "ENGINE_DATA", 0), | ||||
|         ("SPEED", "ENGINE_DATA", 0), | ||||
|         ("RES", "CRZ_BTNS", 0), | ||||
|         ("SET_P", "CRZ_BTNS", 0), | ||||
|         ("SET_M", "CRZ_BTNS", 0), | ||||
|         ("CTR", "CRZ_BTNS", 0), | ||||
|       ] | ||||
| 
 | ||||
|       checks += [ | ||||
|         ("ENGINE_DATA", 100), | ||||
|         ("CRZ_CTRL", 50), | ||||
|         ("CRZ_BTNS", 10), | ||||
|         ("PEDALS", 50), | ||||
|         ("BRAKE", 50), | ||||
|         ("SEATBELT", 10), | ||||
|         ("DOORS", 10), | ||||
|         ("GEAR", 20), | ||||
|       ] | ||||
| 
 | ||||
|     return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 0) | ||||
| 
 | ||||
| 
 | ||||
|   @staticmethod | ||||
|   def get_cam_can_parser(CP): | ||||
|     signals = [ ] | ||||
|     checks = [ ] | ||||
| 
 | ||||
|     if CP.carFingerprint == CAR.CX5: | ||||
|       signals += [ | ||||
|         # sig_name, sig_address, default | ||||
|         ("LKAS_REQUEST",     "CAM_LKAS", 0), | ||||
|         ("CTR",              "CAM_LKAS", 0), | ||||
|         ("ERR_BIT_1",        "CAM_LKAS", 0), | ||||
|         ("LINE_NOT_VISIBLE", "CAM_LKAS", 0), | ||||
|         ("LDW",              "CAM_LKAS", 0), | ||||
|         ("BIT_1",            "CAM_LKAS", 1), | ||||
|         ("ERR_BIT_2",        "CAM_LKAS", 0), | ||||
|         ("STEERING_ANGLE",   "CAM_LKAS", 0), | ||||
|         ("ANGLE_ENABLED",    "CAM_LKAS", 0), | ||||
|         ("CHKSUM",           "CAM_LKAS", 0), | ||||
|       ] | ||||
| 
 | ||||
|       checks += [ | ||||
|         # sig_address, frequency | ||||
|         ("CAM_LKAS",      16), | ||||
|       ] | ||||
| 
 | ||||
|     return CANParser(DBC[CP.carFingerprint]['pt'], signals, checks, 2) | ||||
| 
 | ||||
| @ -0,0 +1,94 @@ | ||||
| #!/usr/bin/env python3 | ||||
| from cereal import car | ||||
| from selfdrive.config import Conversions as CV | ||||
| from selfdrive.car.mazda.values import CAR, LKAS_LIMITS, FINGERPRINTS, ECU_FINGERPRINT, Ecu | ||||
| from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, is_ecu_disconnected | ||||
| from selfdrive.car.interfaces import CarInterfaceBase | ||||
| 
 | ||||
| ButtonType = car.CarState.ButtonEvent.Type | ||||
| EventName = car.CarEvent.EventName | ||||
| 
 | ||||
| class CarInterface(CarInterfaceBase): | ||||
| 
 | ||||
|   @staticmethod | ||||
|   def compute_gb(accel, speed): | ||||
|     return float(accel) / 4.0 | ||||
| 
 | ||||
|   @staticmethod | ||||
|   def get_params(candidate, fingerprint=gen_empty_fingerprint(), has_relay=False, car_fw=[]): | ||||
|     ret = CarInterfaceBase.get_std_params(candidate, fingerprint, has_relay) | ||||
| 
 | ||||
|     ret.carName = "mazda" | ||||
|     ret.safetyModel = car.CarParams.SafetyModel.mazda | ||||
| 
 | ||||
|     ret.dashcamOnly = True | ||||
| 
 | ||||
|     ret.radarOffCan = True | ||||
| 
 | ||||
|     # Mazda port is a community feature for now | ||||
|     ret.communityFeature = True | ||||
| 
 | ||||
|     ret.steerActuatorDelay = 0.1 | ||||
|     ret.steerRateCost = 1.0 | ||||
|     ret.steerLimitTimer = 0.8 | ||||
|     tire_stiffness_factor = 0.70   # not optimized yet | ||||
| 
 | ||||
|     if candidate in [CAR.CX5]: | ||||
|       ret.mass =  3655 * CV.LB_TO_KG + STD_CARGO_KG | ||||
|       ret.wheelbase = 2.7 | ||||
|       ret.steerRatio = 15.5 | ||||
| 
 | ||||
|       ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] | ||||
|       ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.2], [0.2]] | ||||
| 
 | ||||
|       ret.lateralTuning.pid.kf = 0.00006 | ||||
| 
 | ||||
|       # No steer below disable speed | ||||
|       ret.minSteerSpeed = LKAS_LIMITS.DISABLE_SPEED * CV.KPH_TO_MS | ||||
| 
 | ||||
| 
 | ||||
|     ret.centerToFront = ret.wheelbase * 0.41 | ||||
| 
 | ||||
|     # TODO: get actual value, for now starting with reasonable value for | ||||
|     # civic and scaling by mass and wheelbase | ||||
|     ret.rotationalInertia = scale_rot_inertia(ret.mass, ret.wheelbase) | ||||
| 
 | ||||
|     # TODO: start from empirically derived lateral slip stiffness for the civic and scale by | ||||
|     # mass and CG position, so all cars will have approximately similar dyn behaviors | ||||
|     ret.tireStiffnessFront, ret.tireStiffnessRear = scale_tire_stiffness(ret.mass, ret.wheelbase, ret.centerToFront, | ||||
|                                                                          tire_stiffness_factor=tire_stiffness_factor) | ||||
| 
 | ||||
|     ret.enableCamera = is_ecu_disconnected(fingerprint[0], FINGERPRINTS, ECU_FINGERPRINT, candidate, Ecu.fwdCamera) or has_relay | ||||
| 
 | ||||
|     return ret | ||||
| 
 | ||||
|   # returns a car.CarState | ||||
|   def update(self, c, can_strings): | ||||
| 
 | ||||
|     self.cp.update_strings(can_strings) | ||||
|     self.cp_cam.update_strings(can_strings) | ||||
| 
 | ||||
|     ret = self.CS.update(self.cp, self.cp_cam) | ||||
|     ret.canValid = self.cp.can_valid and self.cp_cam.can_valid | ||||
| 
 | ||||
|     # TODO: button presses | ||||
|     ret.buttonEvents = [] | ||||
| 
 | ||||
|     # events | ||||
|     events = self.create_common_events(ret) | ||||
| 
 | ||||
|     if self.CS.low_speed_lockout: | ||||
|       events.add(EventName.speedTooLow) | ||||
| 
 | ||||
|     if self.CS.low_speed_alert: | ||||
|       events.add(EventName.belowSteerSpeed) | ||||
| 
 | ||||
|     ret.events = events.to_msg() | ||||
| 
 | ||||
|     self.CS.out = ret.as_reader() | ||||
|     return self.CS.out | ||||
| 
 | ||||
|   def apply(self, c): | ||||
|     can_sends = self.CC.update(c.enabled, self.CS, self.frame, c.actuators) | ||||
|     self.frame += 1 | ||||
|     return can_sends | ||||
| @ -0,0 +1,104 @@ | ||||
| from selfdrive.car.mazda.values import CAR, Buttons | ||||
| 
 | ||||
| def create_steering_control(packer, car_fingerprint, frame, apply_steer, lkas): | ||||
| 
 | ||||
|   tmp = apply_steer + 2048 | ||||
| 
 | ||||
|   lo = tmp & 0xFF | ||||
|   hi = tmp >> 8 | ||||
| 
 | ||||
|   b1 = int(lkas["BIT_1"]) | ||||
|   ldw = int(lkas["LDW"]) | ||||
|   er1= int(lkas["ERR_BIT_1"]) | ||||
|   lnv = 0 | ||||
|   er2= int(lkas["ERR_BIT_2"]) | ||||
| 
 | ||||
|   steering_angle = int(lkas["STEERING_ANGLE"]) | ||||
|   b2 = int(lkas["ANGLE_ENABLED"]) | ||||
| 
 | ||||
|   tmp = steering_angle + 2048 | ||||
|   ahi =  tmp >> 10 | ||||
|   amd =  (tmp  & 0x3FF) >> 2 | ||||
|   amd =  (amd >> 4) | (( amd & 0xF) << 4) | ||||
|   alo =  (tmp & 0x3) << 2 | ||||
| 
 | ||||
|   ctr = frame % 16 | ||||
|   # bytes:     [    1  ] [ 2 ] [             3               ]  [           4         ] | ||||
|   csum = 249 - ctr - hi - lo - (lnv << 3) - er1  - (ldw << 7) - ( er2 << 4) - (b1 << 5) | ||||
| 
 | ||||
|   #bytes       [ 5 ] [ 6 ] [    7   ] | ||||
|   csum = csum - ahi - amd - alo - b2 | ||||
| 
 | ||||
|   if ahi == 1: | ||||
|     csum = csum + 15 | ||||
| 
 | ||||
|   if csum < 0: | ||||
|     if csum < -256: | ||||
|       csum = csum + 512 | ||||
|     else: | ||||
|       csum = csum + 256 | ||||
| 
 | ||||
|   csum = csum % 256 | ||||
| 
 | ||||
|   if car_fingerprint == CAR.CX5: | ||||
|     values = { | ||||
|       "LKAS_REQUEST"     : apply_steer, | ||||
|       "CTR"              : ctr, | ||||
|       "ERR_BIT_1"        : er1, | ||||
|       "LINE_NOT_VISIBLE" : lnv, | ||||
|       "LDW"              : ldw, | ||||
|       "BIT_1"            : b1, | ||||
|       "ERR_BIT_2"        : er2, | ||||
|       "STEERING_ANGLE"   : steering_angle, | ||||
|       "ANGLE_ENABLED"    : b2, | ||||
|       "CHKSUM"           : csum | ||||
|     } | ||||
| 
 | ||||
|   return packer.make_can_msg("CAM_LKAS", 0, values) | ||||
| 
 | ||||
| 
 | ||||
| def create_button_cmd(packer, car_fingerprint, button): | ||||
| 
 | ||||
|   if button == Buttons.CANCEL: | ||||
|     can = 1 | ||||
|     res = 0 | ||||
|   elif button == Buttons.RESUME: | ||||
|     can = 0 | ||||
|     res = 1 | ||||
|   else: | ||||
|     can = 0 | ||||
|     res = 0 | ||||
| 
 | ||||
|   if car_fingerprint == CAR.CX5: | ||||
|     values = { | ||||
|       "CAN_OFF"           : can, | ||||
|       "CAN_OFF_INV"       : (can + 1) % 2, | ||||
| 
 | ||||
|       "SET_P"             : 0, | ||||
|       "SET_P_INV"         : 1, | ||||
| 
 | ||||
|       "RES"               : res, | ||||
|       "RES_INV"           : (res + 1) % 2, | ||||
| 
 | ||||
|       "SET_M"             : 0, | ||||
|       "SET_M_INV"         : 1, | ||||
| 
 | ||||
|       "DISTANCE_LESS"     : 0, | ||||
|       "DISTANCE_LESS_INV" : 1, | ||||
| 
 | ||||
|       "DISTANCE_MORE"     : 0, | ||||
|       "DISTANCE_MORE_INV" : 1, | ||||
| 
 | ||||
|       "MODE_X"            : 0, | ||||
|       "MODE_X_INV"        : 1, | ||||
| 
 | ||||
|       "MODE_Y"            : 0, | ||||
|       "MODE_Y_INV"        : 1, | ||||
| 
 | ||||
|       "BIT1"              : 1, | ||||
|       "BIT2"              : 1, | ||||
|       "BIT3"              : 1, | ||||
|       "CTR"               : 0 | ||||
|     } | ||||
| 
 | ||||
|     return packer.make_can_msg("CRZ_BTNS", 0, values) | ||||
| @ -0,0 +1,6 @@ | ||||
| #!/usr/bin/env python3 | ||||
| from selfdrive.car.interfaces import RadarInterfaceBase | ||||
| 
 | ||||
| class RadarInterface(RadarInterfaceBase): | ||||
|   pass | ||||
| 
 | ||||
| @ -0,0 +1,64 @@ | ||||
| from selfdrive.car import dbc_dict | ||||
| from cereal import car | ||||
| Ecu = car.CarParams.Ecu | ||||
| 
 | ||||
| 
 | ||||
| # Steer torque limits | ||||
| 
 | ||||
| class SteerLimitParams: | ||||
|   STEER_MAX = 600                 # max_steer 2048 | ||||
|   STEER_STEP = 1                  # how often we update the steer cmd | ||||
|   STEER_DELTA_UP = 10             # torque increase per refresh | ||||
|   STEER_DELTA_DOWN = 20           # torque decrease per refresh | ||||
|   STEER_DRIVER_ALLOWANCE = 15     # allowed driver torque before start limiting | ||||
|   STEER_DRIVER_MULTIPLIER = 1     # weight driver torque | ||||
|   STEER_DRIVER_FACTOR = 1         # from dbc | ||||
| 
 | ||||
| class CAR: | ||||
|   CX5 = "Mazda CX-5 2017" | ||||
| 
 | ||||
| class LKAS_LIMITS: | ||||
|   STEER_THRESHOLD = 15 | ||||
|   DISABLE_SPEED   = 45  #kph | ||||
|   ENABLE_SPEED    = 52  #kph | ||||
| 
 | ||||
| class Buttons: | ||||
|   NONE = 0 | ||||
|   SET_PLUS = 1 | ||||
|   SET_MINUS = 2 | ||||
|   RESUME = 3 | ||||
|   CANCEL = 4 | ||||
| 
 | ||||
| FINGERPRINTS = { | ||||
|   CAR.CX5: [ | ||||
|     # CX-5 2017 GT | ||||
|     { | ||||
|       64: 8, 70: 8, 80: 8, 117: 8, 118: 8, 120: 8, 121: 8, 130: 8, 134: 8, 145: 8, 154: 8, 155: 8, 157: 8, 158: 8, 159: 8, 253: 8, 304: 8, 305: 8, 357: 8, 358: 8, 359: 8, 512: 8, 514: 8, 515: 8, 529: 8, 533: 8, 535: 8, 539: 8, 540: 8, 541: 8, 542: 8, 543: 8, 552: 8, 576: 8, 577: 8, 578: 8, 579: 8, 580: 8, 581: 8, 582: 8, 605: 8, 606: 8, 607: 8, 608: 8, 628: 8, 832: 8, 836: 8, 863: 8, 865: 8, 866: 8, 867: 8, 868: 8, 869: 8, 870: 8, 976: 8, 977: 8, 978: 8, 1034: 8, 1045: 8, 1056: 8, 1061: 8, 1067: 8, 1070: 8, 1078: 8, 1080: 8, 1085: 8, 1086: 8, 1088: 8, 1093: 8, 1108: 8, 1114: 8, 1115: 8, 1116: 8, 1139: 8, 1143: 8, 1147: 8, 1154: 8, 1157: 8, 1160: 8, 1163: 8, 1166: 8, 1177: 8, 1178: 8, 1179: 8, 1180: 8, 1183: 8, 1233: 8, 1236: 8, 1237: 8, 1238: 8, 1239: 8, 1241: 8, 1242: 8, 1243: 8, 1244: 8, 1264: 8, 1266: 8, 1267: 8, 1269: 8, 1270: 8, 1271: 8, 1272: 8, 1274: 8, 1275: 8, 1277: 8, 1278: 8, 1409: 8, 1416: 8, 1425: 8, 1430: 8, 1435: 8, 1440: 8, 1446: 8, 1456: 8, 1479: 8 | ||||
|     }, | ||||
| 
 | ||||
|     # CX-5 2019 GTR | ||||
|     { | ||||
|       64: 8, 70: 8, 80: 8, 117: 8, 118: 8, 120: 8, 121: 8, 130: 8, 134: 8, 145: 8, 154: 8, 155: 8, 157: 8, 158: 8, 159: 8, 253: 8, 254: 8, 304: 8, 305: 8, 357: 8, 358: 8, 359: 8, 512: 8, 514: 8, 515: 8, 529: 8, 533: 8, 535: 8, 539: 8, 540: 8, 541: 8, 542: 8, 543: 8, 552: 8, 576: 8, 577: 8, 578: 8, 579: 8, 580: 8, 581: 8, 582: 8, 605: 8, 606: 8, 607: 8, 608: 8, 628: 8, 736: 8, 832: 8, 836: 8, 863: 8, 865: 8, 866: 8, 867: 8, 868: 8, 869: 8, 870: 8, 976: 8, 977: 8, 978: 8, 1034: 8, 1045: 8, 1056: 8, 1061: 8, 1067: 8, 1078: 8, 1080: 8, 1085: 8, 1086: 8, 1088: 8, 1093: 8, 1108: 8, 1114: 8, 1115: 8, 1116: 8, 1139: 8, 1143: 8, 1147: 8, 1154: 8, 1157: 8, 1160: 8, 1163: 8, 1166: 8, 1170: 8, 1171: 8, 1173: 8, 1177: 8, 1178: 8, 1179: 8, 1180: 8, 1183: 8, 1233: 8, 1236: 8, 1237: 8, 1238: 8, 1239: 8, 1241: 8, 1242: 8, 1244: 8, 1260: 8, 1264: 8, 1266: 8, 1267: 8, 1269: 8, 1270: 8, 1271: 8, 1272: 8, 1274: 8, 1277: 8, 1278: 8, 1409: 8, 1416: 8, 1425: 8, 1430: 8, 1435: 8, 1440: 8, 1446: 8, 1456: 8, 1479: 8, 1776: 8, 1792: 8, 1872: 8, 1937: 8, 1953: 8, 1968: 8, 2015: 8, 2016: 8, 2024: 8 | ||||
|     }, | ||||
| 
 | ||||
|     # Mazda 6 2017 GT | ||||
|     { | ||||
|       64: 8, 70: 8, 80: 8, 117: 8, 118: 8, 120: 8, 121: 8, 130: 8, 134: 8, 145: 8, 154: 8, 155: 8, 157: 8, 158: 8, 159: 8, 253: 8, 304: 8, 305: 8, 357: 8, 358: 8, 359: 8, 512: 8, 514: 8, 515: 8, 529: 8, 533: 8, 535: 8, 539: 8, 540: 8, 541: 8, 542: 8, 543: 8, 552: 8, 576: 8, 577: 8, 578: 8, 579: 8, 580: 8, 581: 8, 582: 8, 605: 8, 606: 8, 607: 8, 628: 8, 832: 8, 836: 8, 863: 8, 865: 8, 866: 8, 867: 8, 868: 8, 869: 8, 870: 8, 976: 8, 977: 8, 978: 8, 1034: 8, 1045: 8, 1056: 8, 1061: 8, 1067: 8, 1070: 8, 1078: 8, 1080: 8, 1085: 8, 1086: 8, 1088: 8, 1093: 8, 1108: 8, 1114: 8, 1115: 8, 1116: 8, 1143: 8, 1147: 8, 1154: 8, 1157: 8, 1160: 8, 1163: 8, 1166: 8, 1177: 8, 1178: 8, 1179: 8, 1180: 8, 1182: 8, 1183: 8, 1233: 8, 1236: 8, 1237: 8, 1238: 8, 1239: 8, 1241: 8, 1242: 8, 1243: 8, 1244: 8, 1264: 8, 1266: 8, 1267: 8, 1269: 8, 1270: 8, 1271: 8, 1272: 8, 1274: 8, 1275: 8, 1277: 8, 1278: 8, 1409: 8, 1416: 8, 1425: 8, 1430: 8, 1435: 8, 1440: 8, 1456: 8, 1479: 8 | ||||
|     }, | ||||
| 
 | ||||
|     # CX-9 2017 Australia | ||||
|     { | ||||
|       64: 8, 70: 8, 80: 8, 117: 8, 118: 8, 120: 8, 121: 8, 130: 8, 134: 8, 138: 8, 145: 8, 154: 8, 155: 8, 157: 8, 158: 8, 159: 8, 253: 8, 304: 8, 305: 8, 357: 8, 358: 8, 359: 8, 512: 8, 514: 8, 515: 8, 522: 8, 529: 8, 533: 8, 535: 8, 539: 8, 540: 8, 541: 8, 542: 8, 543: 8, 552: 8, 576: 8, 577: 8, 578: 8, 579: 8, 580: 8, 581: 8, 582: 8, 583: 8, 605: 8, 606: 8, 628: 8, 832: 8, 976: 8, 977: 8, 978: 8, 1034: 8, 1045: 8, 1056: 8, 1061: 8, 1067: 8, 1078: 8, 1085: 8, 1086: 8, 1088: 8, 1093: 8, 1108: 8, 1114: 8, 1115: 8, 1116: 8, 1139: 8, 1143: 8, 1147: 8, 1154: 8, 1157: 8, 1160: 8, 1163: 8, 1166: 8, 1170: 8, 1177: 8, 1180: 8, 1183: 8, 1233: 8, 1236: 8, 1237: 8, 1238: 8, 1239: 8, 1241: 8, 1242: 8, 1243: 8, 1244: 8, 1247: 8, 1264: 8, 1266: 8, 1267: 8, 1269: 8, 1271: 8, 1272: 8, 1274: 8, 1277: 8, 1278: 8, 1409: 8, 1416: 8, 1425: 8, 1430: 8, 1435: 8, 1440: 8, 1446: 8, 1456: 8, 1479: 8 | ||||
|     }, | ||||
|   ], | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| ECU_FINGERPRINT = { | ||||
|   Ecu.fwdCamera: [579],   # steer torque cmd | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| DBC = { | ||||
|   CAR.CX5: dbc_dict('mazda_2017', None), | ||||
| } | ||||
					Loading…
					
					
				
		Reference in new issue