subarucan.py 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. from cereal import car
  2. from openpilot.selfdrive.car.subaru.values import CanBus
  3. VisualAlert = car.CarControl.HUDControl.VisualAlert
  4. def create_steering_control(packer, apply_steer, steer_req):
  5. values = {
  6. "LKAS_Output": apply_steer,
  7. "LKAS_Request": steer_req,
  8. "SET_1": 1
  9. }
  10. return packer.make_can_msg("ES_LKAS", 0, values)
  11. def create_steering_control_angle(packer, apply_steer, steer_req):
  12. values = {
  13. "LKAS_Output": apply_steer,
  14. "LKAS_Request": steer_req,
  15. "SET_3": 3
  16. }
  17. return packer.make_can_msg("ES_LKAS_ANGLE", 0, values)
  18. def create_steering_status(packer):
  19. return packer.make_can_msg("ES_LKAS_State", 0, {})
  20. def create_es_distance(packer, frame, es_distance_msg, bus, pcm_cancel_cmd, long_enabled = False, brake_cmd = False, cruise_throttle = 0):
  21. values = {s: es_distance_msg[s] for s in [
  22. "CHECKSUM",
  23. "Signal1",
  24. "Cruise_Fault",
  25. "Cruise_Throttle",
  26. "Signal2",
  27. "Car_Follow",
  28. "Low_Speed_Follow",
  29. "Cruise_Soft_Disable",
  30. "Signal7",
  31. "Cruise_Brake_Active",
  32. "Distance_Swap",
  33. "Cruise_EPB",
  34. "Signal4",
  35. "Close_Distance",
  36. "Signal5",
  37. "Cruise_Cancel",
  38. "Cruise_Set",
  39. "Cruise_Resume",
  40. "Signal6",
  41. ]}
  42. values["COUNTER"] = frame % 0x10
  43. if long_enabled:
  44. values["Cruise_Throttle"] = cruise_throttle
  45. # Do not disable openpilot on Eyesight Soft Disable, if openpilot is controlling long
  46. values["Cruise_Soft_Disable"] = 0
  47. values["Cruise_Fault"] = 0
  48. values["Cruise_Brake_Active"] = brake_cmd
  49. if pcm_cancel_cmd:
  50. values["Cruise_Cancel"] = 1
  51. values["Cruise_Throttle"] = 1818 # inactive throttle
  52. return packer.make_can_msg("ES_Distance", bus, values)
  53. def create_es_lkas_state(packer, frame, es_lkas_state_msg, enabled, visual_alert, left_line, right_line, left_lane_depart, right_lane_depart):
  54. values = {s: es_lkas_state_msg[s] for s in [
  55. "CHECKSUM",
  56. "LKAS_Alert_Msg",
  57. "Signal1",
  58. "LKAS_ACTIVE",
  59. "LKAS_Dash_State",
  60. "Signal2",
  61. "Backward_Speed_Limit_Menu",
  62. "LKAS_Left_Line_Enable",
  63. "LKAS_Left_Line_Light_Blink",
  64. "LKAS_Right_Line_Enable",
  65. "LKAS_Right_Line_Light_Blink",
  66. "LKAS_Left_Line_Visible",
  67. "LKAS_Right_Line_Visible",
  68. "LKAS_Alert",
  69. "Signal3",
  70. ]}
  71. values["COUNTER"] = frame % 0x10
  72. # Filter the stock LKAS "Keep hands on wheel" alert
  73. if values["LKAS_Alert_Msg"] == 1:
  74. values["LKAS_Alert_Msg"] = 0
  75. # Filter the stock LKAS sending an audible alert when it turns off LKAS
  76. if values["LKAS_Alert"] == 27:
  77. values["LKAS_Alert"] = 0
  78. # Filter the stock LKAS sending an audible alert when "Keep hands on wheel" alert is active (2020+ models)
  79. if values["LKAS_Alert"] == 28 and values["LKAS_Alert_Msg"] == 7:
  80. values["LKAS_Alert"] = 0
  81. # Filter the stock LKAS sending an audible alert when "Keep hands on wheel OFF" alert is active (2020+ models)
  82. if values["LKAS_Alert"] == 30:
  83. values["LKAS_Alert"] = 0
  84. # Filter the stock LKAS sending "Keep hands on wheel OFF" alert (2020+ models)
  85. if values["LKAS_Alert_Msg"] == 7:
  86. values["LKAS_Alert_Msg"] = 0
  87. # Show Keep hands on wheel alert for openpilot steerRequired alert
  88. if visual_alert == VisualAlert.steerRequired:
  89. values["LKAS_Alert_Msg"] = 1
  90. # Ensure we don't overwrite potentially more important alerts from stock (e.g. FCW)
  91. if visual_alert == VisualAlert.ldw and values["LKAS_Alert"] == 0:
  92. if left_lane_depart:
  93. values["LKAS_Alert"] = 12 # Left lane departure dash alert
  94. elif right_lane_depart:
  95. values["LKAS_Alert"] = 11 # Right lane departure dash alert
  96. if enabled:
  97. values["LKAS_ACTIVE"] = 1 # Show LKAS lane lines
  98. values["LKAS_Dash_State"] = 2 # Green enabled indicator
  99. else:
  100. values["LKAS_Dash_State"] = 0 # LKAS Not enabled
  101. values["LKAS_Left_Line_Visible"] = int(left_line)
  102. values["LKAS_Right_Line_Visible"] = int(right_line)
  103. return packer.make_can_msg("ES_LKAS_State", CanBus.main, values)
  104. def create_es_dashstatus(packer, frame, dashstatus_msg, enabled, long_enabled, long_active, lead_visible):
  105. values = {s: dashstatus_msg[s] for s in [
  106. "CHECKSUM",
  107. "PCB_Off",
  108. "LDW_Off",
  109. "Signal1",
  110. "Cruise_State_Msg",
  111. "LKAS_State_Msg",
  112. "Signal2",
  113. "Cruise_Soft_Disable",
  114. "Cruise_Status_Msg",
  115. "Signal3",
  116. "Cruise_Distance",
  117. "Signal4",
  118. "Conventional_Cruise",
  119. "Signal5",
  120. "Cruise_Disengaged",
  121. "Cruise_Activated",
  122. "Signal6",
  123. "Cruise_Set_Speed",
  124. "Cruise_Fault",
  125. "Cruise_On",
  126. "Display_Own_Car",
  127. "Brake_Lights",
  128. "Car_Follow",
  129. "Signal7",
  130. "Far_Distance",
  131. "Cruise_State",
  132. ]}
  133. values["COUNTER"] = frame % 0x10
  134. if long_enabled:
  135. values["Cruise_State"] = 0
  136. values["Cruise_Activated"] = enabled
  137. values["Cruise_Disengaged"] = 0
  138. values["Car_Follow"] = int(lead_visible)
  139. values["PCB_Off"] = 1 # AEB is not presevered, so show the PCB_Off on dash
  140. values["LDW_Off"] = 0
  141. values["Cruise_Fault"] = 0
  142. # Filter stock LKAS disabled and Keep hands on steering wheel OFF alerts
  143. if values["LKAS_State_Msg"] in (2, 3):
  144. values["LKAS_State_Msg"] = 0
  145. return packer.make_can_msg("ES_DashStatus", CanBus.main, values)
  146. def create_es_brake(packer, frame, es_brake_msg, long_enabled, long_active, brake_value):
  147. values = {s: es_brake_msg[s] for s in [
  148. "CHECKSUM",
  149. "Signal1",
  150. "Brake_Pressure",
  151. "AEB_Status",
  152. "Cruise_Brake_Lights",
  153. "Cruise_Brake_Fault",
  154. "Cruise_Brake_Active",
  155. "Cruise_Activated",
  156. "Signal3",
  157. ]}
  158. values["COUNTER"] = frame % 0x10
  159. if long_enabled:
  160. values["Cruise_Brake_Fault"] = 0
  161. values["Cruise_Activated"] = long_active
  162. values["Brake_Pressure"] = brake_value
  163. values["Cruise_Brake_Active"] = brake_value > 0
  164. values["Cruise_Brake_Lights"] = brake_value >= 70
  165. return packer.make_can_msg("ES_Brake", CanBus.main, values)
  166. def create_es_status(packer, frame, es_status_msg, long_enabled, long_active, cruise_rpm):
  167. values = {s: es_status_msg[s] for s in [
  168. "CHECKSUM",
  169. "Signal1",
  170. "Cruise_Fault",
  171. "Cruise_RPM",
  172. "Cruise_Activated",
  173. "Brake_Lights",
  174. "Cruise_Hold",
  175. "Signal3",
  176. ]}
  177. values["COUNTER"] = frame % 0x10
  178. if long_enabled:
  179. values["Cruise_RPM"] = cruise_rpm
  180. values["Cruise_Fault"] = 0
  181. values["Cruise_Activated"] = long_active
  182. return packer.make_can_msg("ES_Status", CanBus.main, values)
  183. def create_es_infotainment(packer, frame, es_infotainment_msg, visual_alert):
  184. # Filter stock LKAS disabled and Keep hands on steering wheel OFF alerts
  185. values = {s: es_infotainment_msg[s] for s in [
  186. "CHECKSUM",
  187. "LKAS_State_Infotainment",
  188. "LKAS_Blue_Lines",
  189. "Signal1",
  190. "Signal2",
  191. ]}
  192. values["COUNTER"] = frame % 0x10
  193. if values["LKAS_State_Infotainment"] in (3, 4):
  194. values["LKAS_State_Infotainment"] = 0
  195. # Show Keep hands on wheel alert for openpilot steerRequired alert
  196. if visual_alert == VisualAlert.steerRequired:
  197. values["LKAS_State_Infotainment"] = 3
  198. # Show Obstacle Detected for fcw
  199. if visual_alert == VisualAlert.fcw:
  200. values["LKAS_State_Infotainment"] = 2
  201. return packer.make_can_msg("ES_Infotainment", CanBus.main, values)
  202. def create_es_highbeamassist(packer):
  203. values = {
  204. "HBA_Available": False,
  205. }
  206. return packer.make_can_msg("ES_HighBeamAssist", CanBus.main, values)
  207. def create_es_static_1(packer):
  208. values = {
  209. "SET_3": 3,
  210. }
  211. return packer.make_can_msg("ES_STATIC_1", CanBus.main, values)
  212. def create_es_static_2(packer):
  213. values = {
  214. "SET_3": 3,
  215. }
  216. return packer.make_can_msg("ES_STATIC_2", CanBus.main, values)
  217. # *** Subaru Pre-global ***
  218. def subaru_preglobal_checksum(packer, values, addr, checksum_byte=7):
  219. dat = packer.make_can_msg(addr, 0, values)[2]
  220. return (sum(dat[:checksum_byte]) + sum(dat[checksum_byte+1:])) % 256
  221. def create_preglobal_steering_control(packer, frame, apply_steer, steer_req):
  222. values = {
  223. "COUNTER": frame % 0x08,
  224. "LKAS_Command": apply_steer,
  225. "LKAS_Active": steer_req,
  226. }
  227. values["Checksum"] = subaru_preglobal_checksum(packer, values, "ES_LKAS")
  228. return packer.make_can_msg("ES_LKAS", CanBus.main, values)
  229. def create_preglobal_es_distance(packer, cruise_button, es_distance_msg):
  230. values = {s: es_distance_msg[s] for s in [
  231. "Cruise_Throttle",
  232. "Signal1",
  233. "Car_Follow",
  234. "Signal2",
  235. "Cruise_Brake_Active",
  236. "Distance_Swap",
  237. "Standstill",
  238. "Signal3",
  239. "Close_Distance",
  240. "Signal4",
  241. "Standstill_2",
  242. "Cruise_Fault",
  243. "Signal5",
  244. "COUNTER",
  245. "Signal6",
  246. "Cruise_Button",
  247. "Signal7",
  248. ]}
  249. values["Cruise_Button"] = cruise_button
  250. values["Checksum"] = subaru_preglobal_checksum(packer, values, "ES_Distance")
  251. return packer.make_can_msg("ES_Distance", CanBus.main, values)