import struct import common.numpy_fast as np from selfdrive.config import Conversions as CV # *** Honda specific *** def can_cksum(mm): s = 0 for c in mm: c = ord(c) s += (c>>4) s += c & 0xF s = 8-s s %= 0x10 return s def fix(msg, addr): msg2 = msg[0:-1] + chr(ord(msg[-1]) | can_cksum(struct.pack("I", addr)+msg)) return msg2 def make_can_msg(addr, dat, idx, alt): if idx is not None: dat += chr(idx << 4) dat = fix(dat, addr) return [addr, 0, dat, alt] def create_brake_command(apply_brake, pcm_override, pcm_cancel_cmd, chime, idx): """Creates a CAN message for the Honda DBC BRAKE_COMMAND.""" pump_on = apply_brake > 0 brakelights = apply_brake > 0 brake_rq = apply_brake > 0 pcm_fault_cmd = False amount = struct.pack("!H", (apply_brake << 6) + pump_on) msg = amount + struct.pack("BBB", (pcm_override << 4) | (pcm_fault_cmd << 2) | (pcm_cancel_cmd << 1) | brake_rq, 0x80, brakelights << 7) + chr(chime) + "\x00" return make_can_msg(0x1fa, msg, idx, 0) def create_gas_command(gas_amount, idx): """Creates a CAN message for the Honda DBC GAS_COMMAND.""" msg = struct.pack("!H", gas_amount) return make_can_msg(0x200, msg, idx, 0) def create_accord_steering_control(apply_steer, idx): # TODO: doesn't work for some reason if apply_steer == 0: dat = [0, 0, 0x40, 0] else: dat = [0,0,0,0] rp = np.clip(apply_steer/0xF, -0xFF, 0xFF) if rp < 0: rp += 512 dat[0] |= (rp >> 5) & 0xf dat[1] |= (rp) & 0x1f if idx == 1: dat[0] |= 0x20 dat[1] |= 0x20 # always dat[3] = -(dat[0]+dat[1]+dat[2]) & 0x7f # not first byte dat[1] |= 0x80 dat[2] |= 0x80 dat[3] |= 0x80 dat = ''.join(map(chr, dat)) return [0,0,dat,8] def create_steering_control(apply_steer, idx): """Creates a CAN message for the Honda DBC STEERING_CONTROL.""" msg = struct.pack("!h", apply_steer) + ("\x80\x00" if apply_steer != 0 else "\x00\x00") return make_can_msg(0xe4, msg, idx, 0) def create_ui_commands(pcm_speed, hud, civic, accord, idx): """Creates an iterable of CAN messages for the UIs.""" commands = [] pcm_speed_real = np.clip(int(round(pcm_speed / 0.002759506)), 0, 64000) # conversion factor from dbc file msg_0x30c = struct.pack("!HBBBBB", pcm_speed_real, hud.pcm_accel, hud.v_cruise, hud.X2, hud.car, hud.X4) commands.append(make_can_msg(0x30c, msg_0x30c, idx, 0)) 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 msg_0x35e = chr(0) * 7 commands.append(make_can_msg(0x35e, msg_0x35e, idx, 0)) if civic or accord: 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, 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) speed = struct.pack('!B', v_ego_kph) msg_0x300 = ("\xf9" + speed + "\x8a\xd0" +\ ("\x20" if idx == 0 or idx == 3 else "\x00") +\ "\x00\x00") if civic: msg_0x301 = "\x02\x38\x44\x32\x4f\x00\x00" # add 8 on idx. commands.append(make_can_msg(0x300, msg_0x300, idx + 8, 1)) elif accord: # 0300( 768)( 69) f9008ad0100000ef # 0301( 769)( 69) 0ed8522256000029 msg_0x301 = "\x0e\xd8\x52\x22\x56\x00\x00" # add 0xc on idx? WTF is this? commands.append(make_can_msg(0x300, msg_0x300, idx + 0xc, 1)) else: msg_0x301 = "\x0f\x18\x51\x02\x5a\x00\x00" commands.append(make_can_msg(0x300, msg_0x300, idx, 1)) commands.append(make_can_msg(0x301, msg_0x301, idx, 1)) return commands