标签: Hyundai

  • Hyundai 车辆输入:经典 CAN、CAN FD 与按钮意图的边界

    结论:Hyundai 的车辆输入不能按「同品牌即同契约」理解:经典 CAN 把 Bus.pt 映射到物理 0、Bus.cam 映射到 2,而 CAN FD 的动力/相机总线取决于 CanBus(CP).ECAN/CAM,LKA 转向平台还会交换 A-CAN 与 E-CAN,所以不能把「E-CAN 总是 0」写死到线束或接口。另一个易误解点是按钮意图:recent_button_interaction() 检查的是最近八个报文样本而非固定八帧或 80 ms 窗口,无新样本时旧交互可能跨多个调用继续被视为「最近」。本文为固定源码快照 c8fb906 的静态阅读,未运行回放、未连接 CAN FD 硬件。

    组件与关键函数

    CarState.__init__() 根据车型 flags 选择档位、踏板、按钮报文及 DBC 枚举,建立八样本按钮队列、仪表速度采样器和控制参数;CarState.update() 做经典 CAN 车辆状态归一化,CAN FD 车型转给 update_canfd()。总线与解析器由 get_can_parsers()/get_can_parsers_canfd() 分别建立,CarInterfaceBase.update() 先更新解析器再归一化,并汇总 canValid、canTimeout。

    入口 职责 边界
    CanBus.__init__() 依据 LKA 转向架构交换 A-CAN/E-CAN,并按安全配置数计算端口偏移 插件不能把「E-CAN 总是 0」写死
    recent_button_interaction() 判断八个最近巡航/主开关样本是否出现驾驶员启用意图 是样本数而非固定帧数或固定时间窗
    create_button_events() 由当前/上次状态合成按下和释放事件 中间报文过渡不会自动逐个转成事件
    CarEvents.update() 在 PCM 巡航启用上升沿,结合 blockPcmEnable 决定是否生成启用事件 仅上升沿且未被阻断时才生成

    总线与解析健康

    车型接口先用相机/动力 fingerprint 推导 LKA、备用按钮、档位及 SCC flags,状态解码依赖这些参数已经正确生成。经典 CAN 的两个解析器起初都不预注册报文;CAN FD 非备用按钮路径仅将 CRUISE_BUTTONS 以 1 Hz 预注册,源码注释说明它名义 50 Hz、但 ECU 可停止约半秒;备用按钮路径则不预注册该报文。其余读取 cp.vl[...] 会动态注册 DBC 报文,而 vl_all 自身不具有动态注册能力。

    概念 确切含义 常见误读
    动态注册时机 发生在本轮 CANParser.update() 之后 首轮此前到达的新报文不在缓存中,零初值不代表物理零测量
    vl_all 本轮样本 每轮清空,只加入成功解码的帧;最近值 vl 保留到下次成功帧 不能用 vl 推断某值采自当前周期
    canValid 所有已注册报文的聚合活性/计数器判据 不是逐字段新鲜度证明
    canTimeout 总线空窗判据 不能说明某个 vl 值恰好来自当前周期

    1 Hz 预注册只是调整该按钮报文的超时判据,不表示发送频率真的 1 Hz。

    经典 CAN 状态路径

    CLU11 决定 kph/mph,四轮 WHL_SPD11 通过基类 parse_wheel_speeds() 进入 vEgoRaw 和 KF1D;但 standstill 只比较左前与右后两轮,阈值为 12 * 0.03125,不是四轮均值。CLU15 仪表车速初始在第一次更新被采样,之后计数器从 0 增至大于 20 才再采一次,即正常每 21 次 CarState.update() 重采;非 Sorento 的英制仪表分支另作向下取整换算,再由基类接口对 vEgoCluster 做迟滞/低速截零,这不是轮速 KF1D 的原始速度。

    SAS11 给方向盘角与角速度,MDPS12 给驾驶员/电机扭矩和临时转向故障。驾驶员施力调用基类计数去抖(阈值 5),方向灯则按灯状态延续 50 次调用,二者与 Toyota 的直接扭矩阈值不同。巡航来源由 CAMERA_SCC 决定:原车纵向读动力或相机 SCC11/SCC12,自控纵向则从动力 TCS13 得到 available/enabled,并明确这些字段不用于实际启停按钮判决。刹车 DriverOverride==2 包含混动/电动车驾驶员再生制动;油门和档位再按 ICE/EV/HYBRID/FCEV flags 分报文。USE_FCA 决定原车 AEB/FCW 来源,HAS_BSM 才读 LCA11。相机 LKAS11 和动力 CLU11 被浅拷贝作为控制器构帧模板,它们是解析器最新缓存,状态函数没有单独验证每个字段的年龄。

    CAN FD 状态路径

    CAN FD 的档位消息在 ACCELERATOR、GEAR_ALT、GEAR_ALT_2、GEAR_SHIFTER 中选;踏板消息也分 EV/HYBRID/其他。CRUISE_BUTTONS_ALT.DISTANCE_UNIT 决定仪表单位,轮速四轮全低于阈值才视为停止;转向/扭矩/故障分别来自 STEERING_SENSORS 与 MDPS。TCS.ACCEnable 决定巡航可用,自动纵向用 TCS.ACC_REQ 作启用状态;原车纵向则按 CANFD_CAMERA_SCC 从相机或动力 SCC_CONTROL 读取启用、停止和设定速度。EV 平台另以 MANUAL_SPEED_LIMIT_ASSIST.MSLA_ENABLED 标记 nonAdaptive,与自适应 ACC 启用不是同一个概念。LKA 转向车还缓存相机 CAM_0x2a4/0x362 供后续 LFA 抑制帧保留原字段,同样没有逐字段新鲜度检查。

    按钮历史、边沿和下游

    经典 CAN 从 CLU11、CAN FD 从选定 CRUISE_BUTTONS 报文的 vl_all 取得本轮可能多条按钮样本,追加到最长 8 条的队列。recent_button_interaction() 检查最近八个报文样本是否有 RES/SET/CANCEL 或任意主开关非零;无新样本时队列不前进,旧交互可能跨多个调用继续被视为「最近」。另一方面,buttonEvents 只比较队列本轮前的末尾与追加后的末尾,一轮内多个中间跳变不会逐个变成事件。blockPcmEnable 取该意图判据的反值,CarEvents 仅在 PCM 巡航由未启用变启用且未被阻断时生成 pcmEnable。CAN FD 还保留按钮 COUNTER,控制器构造原车巡航取消/恢复按钮候选时以 CS.buttons_counter + 1 作为输入;缓存字段是最近成功解析值,能构帧不等于 ECU 已接受。

    新硬件与插件契约

    车型输入插件应明确声明 DBC、物理总线与线束拓扑、每个报文的原始样本时间、校验/计数器结果和有效期。驾驶员按钮需要同时提供逐条边沿序列与当前状态;blockPcmEnable 的意图窗口要用样本年龄或实际时间约束,不能让无新帧的旧按钮无限代表当前意图。原车 AEB/FCW、BSM、刹车与转向故障必须保留各自来源和缺测状态,无法验证的关键输入不能默认为安全。非上车验收应按经典 CAN/CAN FD、LKA/LFA 线束、相机/动力 SCC、四类动力踏板、备用按钮及档位组合建立参数矩阵,并注入首轮报文、按钮突发/断流、单轮速度异常、SCC 丢失、相机缓存过期与总线映射错误。

    常见问题

    Hyundai 同品牌车型的 CAN 总线映射是一样的吗?

    不一样。经典 CAN 与 CAN FD 的物理总线不同,LKA 转向平台还会交换 A-CAN 与 E-CAN 并叠加安全配置偏移,所以不能把「E-CAN 总是 0」写死,需按线束与 DBC 核对。

    recent_button_interaction() 是固定八帧窗口吗?

    不是。它检查最近八个报文样本,既不是固定八帧也不是固定 80 ms;无新样本时队列不前进,旧交互可能跨多个调用仍被视为「最近」。

    1 Hz 预注册 CRUISE_BUTTONS 代表该报文真的 1 Hz 吗?

    不代表。预注册只是调整该按钮报文的超时判据;源码注释说明它名义 50 Hz,但 ECU 可停止约半秒。

    能构出取消/恢复巡航帧就代表 ECU 已接受吗?

    不代表。控制器用的是缓存字段(如 CS.buttons_counter + 1)与最近成功解析值,能构帧不等于 ECU 已接受,也不是硬件执行确认。

    延伸阅读

    参考资料

    • 项目 02 —— openpilot-research/HYUNDAI_CARSTATE_CLASSIC_CANFD_INPUT_DEEP_DIVE.md(取用了组件索引、总线与解析健康、经典 CAN/CAN FD 状态路径、按钮边沿与下游、插件契约)。
    • 项目 02 —— openpilot-research/CAR_MESSAGES_FIELD_CONTRACT_DEEP_DIVE.md(仅用于确认归一化结果进入的消息结构位置)。

    说明:本文为对固定源码快照的静态结构分析,未运行完整测试套件、未连接硬件、未验证目标车型的真实参数组合。文中所有阈值、行号索引与配置均出自源文档,标注为未验证的结论保留其原有边界。

    更新记录

    首次发布 2026-10-11 最近核对:2026-10-11

  • Hyundai 接口的 CAN FD 判别、能力位与 ECU 静默恢复边界

    结论:Hyundai 车型接口的能力位是软件决策,不等于目标 ECU 已按请求改变状态。接口按指纹与固件把平台分成 CAN FD 与经典 CAN 两条判别路径,再由相机总线上是否出现 0x50 或 0x110 决定 LKA 还是 LFA 转向,并据此交换 A-CAN / E-CAN;纵向 ECU 静默只在「自控纵向且非相机 SCC」路径发起,且通用 disable_ecu() 的返回布尔值没有在 Hyundai init() 中被汇总,card 在其返回后直接写 ControlsReady。固定快照基线为 c8fb906,未执行 UDS 请求或实车验证。

    入口与函数链

    CarInterfaceBase.get_params() 先装载平台规格和静态 flags,再调用 Hyundai _get_params(),最后计算车辆惯量与轮胎刚度。Hyundai _get_params() 负责分 CAN FD / 经典 CAN,由指纹与固件推导动态标志、纵向能力和 safety 配置。HyundaiFlags 记录车型 / 检测特征,HyundaiSafetyFlags 编码给 MCU 的控制策略,二者不可互换。

    组件 职责
    CarInterfaceBase.get_params() 先装载平台规格与静态 flags,再调用 Hyundai _get_params(),最后算惯量与轮胎刚度。
    CarInterface._get_params() 分 CAN FD / 经典 CAN,由指纹与固件推导动态标志、纵向能力与 safety 配置。
    CanBus.__init__() / CanBusBase.__init__() LKA / LFA 使 A-CAN / E-CAN 互换;安全配置数量决定四路总线偏移。
    CarInterface.init() / deinit() 条件性发 UDS 通信控制禁发 / 恢复请求。
    disable_ecu() 先进入扩展会话,再请求通信控制;返回布尔值,但上层 Hyundai 接口未消费。
    card.controls_update() 首次进入控制时调用接口 init(),其返回后写 ControlsReady。

    CAN FD:相机地址驱动的分支

    _get_params() 先由 CanBus(None, fingerprint).CAM 找相机总线;该总线上出现 0x50 或 0x110 时判为 LKA 转向,否则判为 LFA。随后 CanBus(None, fingerprint, lka_steering) 重新计算 A-CAN / E-CAN:LKA 平台与 LFA 平台交换两条总线。

    CanBusBase 在指纹阶段按非空 bus 最大编号推导四路偏移;运行阶段 CanBus(CP) 则按 safetyConfigs 数量算偏移。因此识别出的拓扑必须与实际 panda / 线束配置一致,不能由车型名称单独推断 E-CAN 号。CAN FD 的 0x1ba、0xFA、0x1cf、0x130、0x40 等地址参与 BSM、混动、备用按钮和档位报文推断。

    LKA 平台若相机有 0x110,再加 ALT LKA 标志;非 LKA 平台在没有 CANFD_RADAR_SCC 静态标志时,推导相机 SCC。CANFD_NO_RADAR_DISABLE 会关掉实验纵向可用性;LKA 平台若 car_fw 未列出 ADAS ECU,也会关掉。这些是保守能力判据,但空固件列表与「已证明车辆无 ADAS ECU」不能画等号。CAN FD 默认以 hyundaiCanfd 作为执行 safety;若推导出的 E-CAN 编号至少为 4,则在安全配置列表前插入一个 noOutput,由后一个配置承载 Hyundai safety 参数。

    经典 CAN、共同能力与雷达状态

    经典 CAN 在动力总线 0 / 相机总线 2 上按地址判断 BSM、LFA 图标、FCA 报文及 LDA 按钮。LEGACY 平台选 hyundaiLegacy safety,因为旧报文缺计数 / 校验;其他经典平台选 hyundai,相机 SCC 再追加相应 safety 参数。LEGACY 或 UNSUPPORTED_LONGITUDINAL 会使实验纵向不可用。

    两条路径共同设置 0.1 秒转向执行延迟、0.4 秒限制计时器、扭矩标定,以及 ALT_LIMITS / ALT_LIMITS_2 安全标志;后者还使车型 dashcamOnly。特定平台型号另改延迟或设 dashcamOnly。

    概念 边界说明
    openpilotLongitudinalControl 等于 alpha_long and alphaLongitudinalAvailable,pcmCruise 取其反值;只有真正启用时才给 MCU 设 LONG。
    radarUnavailable 仅在 CAN 指纹 bus 1 有雷达起始地址且平台 DBC 提供 Bus.radar 时为假;不是实时雷达在线或诊断静默结果。
    被动回退 card 可因开关关闭、无控制器或 dashcamOnly 把接口设为被动并把安全模式改为 noOutput。
    动力类型 EV / HEV / FCEV 映射为安全参数,但不改变上述能力判定层级。

    车型参数里的 LONG 不是最终上路授权:card 仍可能把接口设为被动并把安全模式改为 noOutput。

    ECU 静默与恢复的实际边界

    CarInterface.init() 仅在自控纵向且非相机 SCC 路径静默纵向 ECU:经典 CAN 及普通 CAN FD 目标为 0x7d0,LKA 转向 CAN FD 改为 E-CAN 的 0x730。默认通信控制请求带 UDS 0x28 的 suppress-positive-response 位;它表示请求 ECU 不发送正响应,不是已经收到确认。若 CANFD_ENABLE_BLINKERS 置位,接口另对 0x7b1 发独立请求;该 flag 在本快照的静态平台项中未见设置。

    通用 disable_ecu() 先要求扩展会话的有效前缀响应,随后以空期望前缀调用通信控制查询并丢弃查询结果;只要后者没有抛异常,就可记录成功。因此其返回真也不等于已验证 0x28 正响应或实际 ECU 停发。Hyundai init() 又没有返回 / 汇总这个布尔值;card 在它返回后直接写 ControlsReady。这是一条源码确认的状态回执缺口,不是对特定车辆雷达或 ADAS ECU 实际行为的断言。

    deinit() 构造启用收发请求并复用 init() 的条件与地址。在本快照的主运行链未检出 CI.deinit() 调用,所以不能说正常退出一定主动恢复 ECU。控制器每 100 帧的 tester-present 也仅在自控纵向、非 CAN FD 相机 SCC 时形成。禁用雷达可能使原车 AEB 不可用,必须逐硬件架构独立验证。

    面向新硬件与插件化的接口建议

    车型插件只应给出期望能力、指纹 / 固件证据、DBC 和拓扑;受信任 ECU 管理服务独占诊断写权限,并单独报告请求已发送、预期正响应或可观测行为、持续存活和恢复结果。不同车型的相机 SCC 与雷达 / ADAS ECU 静默对原车 AEB 的影响,不得合并为一个通用开关。非上车验证矩阵应覆盖 LKA / LFA、相机 / 雷达 SCC、双 panda 总线偏移、备用按钮 / 档位、缺失 ADAS 固件、CANFD_NO_RADAR_DISABLE、负 UDS 响应、超时、掉电恢复及 AEB / FCW。

    常见问题

    为什么不能用车型名直接推断 E-CAN 号?

    因为 E-CAN 号由拓扑推导:指纹阶段 CanBusBase 按非空 bus 最大编号算四路偏移,运行阶段 CanBus(CP) 按 safetyConfigs 数量算偏移;而 LKA 与 LFA 平台会交换 A-CAN / E-CAN。识别出的拓扑必须与实际 panda / 线束配置一致。

    车型参数里 LONG 为真就代表能上纵向控制吗?

    不代表。只有 openpilotLongitudinalControl(即 alpha_long and alphaLongitudinalAvailable)真正启用时才给 MCU 设 LONG;card 还可能因开关关闭、无控制器或 dashcamOnly 把接口设为被动并把安全模式改为 noOutput。

    接口静默雷达 ECU 成功了吗?

    无法从返回值判断。默认请求带 UDS 0x28 suppress-positive-response 位,只是让 ECU 不回正响应;disable_ecu() 丢弃查询结果,返回真也不等于已验证 0x28 正响应或 ECU 实际停发。Hyundai init() 更没有汇总该布尔值。

    退出时会自动恢复被静默的 ECU 吗?

    不能这样假设。deinit() 会构造恢复请求并复用 init() 的条件与地址,但在本快照的主运行链未检出 CI.deinit() 调用。恢复是否发生需按具体运行路径与硬件架构单独验证。

    延伸阅读

    参考资料

    • 项目 02 —— openpilot-research/HYUNDAI_INTERFACE_CAPABILITY_ECU_LIFECYCLE_DEEP_DIVE.md(取用了 CAN FD / 经典 CAN 判别、能力位推导、ECU 静默与恢复边界分析)。

    说明:本文为对固定源码快照的静态结构分析,未运行完整测试套件、未连接硬件、未验证目标车型的真实参数组合。文中所有阈值、行号索引与配置均出自源文档,标注为未验证的结论保留其原有边界。

    更新记录

    首次发布 2026-10-11 最近核对:2026-10-11

  • Hyundai 经典 CAN panda safety:三模式权限矩阵

    结论:Hyundai 经典 CAN panda safety 把「标准雷达 SCC / 标准相机 SCC / Legacy」三种模式做成一张权限矩阵:同一辆车的按钮 RX 固定在 bus 0,而 TX 可能落在 bus 0 或 bus 2,纵向能力只在调试构建生效。Legacy 也不是全面关闭 RX 校验,放宽的只有 0x386 与 0x394,0x260、0x4F1、0x421 仍保留各自的校验或计数门。以下为固定源码快照 c8fb906 的函数级静态分析,不是目标固件或实车验证;bus 号指单个 safety 实例的本地总线编号,车型、线束与 ECU 版本需另行确认。

    初始化与模式选择

    CarInterface._get_params() 在 hyundai 与 hyundaiLegacy 之间选择,并设置相机 SCC 与纵向能力。需要注意的是 openpilotLongitudinalControl 只是上层请求,不是固件准入证明。hyundai_init() 再依据纵向、相机 SCC、FCEV 标志选择 RX 检查表与 TX 白名单;hyundai_legacy_init() 使用 Legacy RX 表,并强制关闭纵向和相机 SCC,仅保留基础 TX 表。

    共享的 hyundai_common_init() 在非调试构建中强制 hyundai_longitudinal=false。也就是说纵向链在源码层面就带着 ALLOW_DEBUG 编译门,不能由 Python 侧 CarParams 位推定量产固件可发。

    模式 SCC12 RX CLU11 TX 纵向/附属 TX 关键差异
    标准雷达 SCC、非纵向 bus 0 bus 0,4 字节 无 SCC TX 巡航接合沿使能;按钮只许受门控的 Resume/Cancel。
    标准相机 SCC、非纵向 bus 2 bus 2,4 字节 无 SCC TX 按钮 RX 仍是 bus 0,不能把 TX 所在总线误当按钮输入来源。
    标准雷达 SCC、纵向 不列为必需 RX bus 0,4 字节 SCC11/12/13/14、FRT_RADAR11、FCA11/12、0x7D0 在 bus 0 LONG 仅 ALLOW_DEBUG 有效;不经原车 SCC 接合沿使能。
    标准相机 SCC、纵向 不列为必需 RX bus 2,4 字节 SCC11/12/13/14、FRT_RADAR11 在 bus 0 相机 SCC 纵向不使用雷达静默诊断白名单。
    Legacy bus 0 bus 0,4 字节 无 SCC TX 强制非纵向、非相机 SCC;仅部分 RX 的完整性检查放宽。

    所有模式均可发送 bus 0 的 0x340 LKAS11 与 0x485 LFAHDA_MFC。纵向 TX 表中的 SCC11/12/13/14 对 bus 0 标记 check_relay=true;若原 ECU 在该总线继续发送同地址帧,共享继电器故障逻辑可阻断 TX。safety_fwd_hook() 只提供通用 bus 0↔2 转发,并静态阻断将 check_relay 地址送往本机 TX 总线,这不是 ECU 已被成功静默的证明。

    RX 完整性与状态消费

    各地址使用不同的计数位与半字节校验:0x386 使用位计数/XOR,其余适用帧使用半字节和。RX 完整性检查先于车型钩子执行,通用 safety_rx_hook() 只在消息匹配、校验有效且属于 RX 表时才调用 hyundai_rx_hook()。

    帧 检查表 实际消费
    0x260 EMS16 或 0x371 E_EMS11 同一备选组;0x260 检查 2 位计数和校验,0x371 忽略二者 ICE 从 0x260 读油门,EV/HEV 从 0x371 读油门。
    0x386 WHL_SPD11 标准模式校验加 4 位计数;Legacy 忽略二者 只用左前、右后轮速判断移动,阈值原始值 12。
    0x394 TCS13 标准模式校验加 3 位计数;Legacy 忽略二者 字节 5 的 DriverOverride 等于 2 判制动。
    0x251 MDPS12 忽略校验/计数,但监视存活 11 位驾驶员扭矩进入共享采样窗口。
    0x4F1 CLU11 忽略校验、检查 4 位计数 bus 0 上解析按钮和主开关,更新近期交互或纵向按钮边沿。
    0x421 SCC12 只在非纵向为必需;校验加 4 位计数 按相机 SCC 标志从 bus 2 或 bus 0 读取 ACC 模式。
    0x91 FCEV 油门 仅特定标准雷达 SCC 或纵向分支附加;忽略校验/计数 FCEV 标志下读取字节 6;标准相机 SCC 非纵向表没有该附加检查。

    FCEV 分支中 0x91 更新油门,但 0x260 的 ICE 回退条件仅排除 EV/HEV;若车辆也出现 0x260,后续该帧仍可能改写油门状态,须用目标车报文核对,不能把单帧观测当成最终状态。

    TX 字段边界与使能条件

    转向 0x340 从 11 位字段还原扭矩与请求位:普通/ALT_LIMITS/ALT_LIMITS_2 的最大扭矩分别为 384/270/170,每帧上升分别为 3/2/2、下降为 7/3/3,均使用实时差 112、驾驶员扭矩余量 50 与请求位节拍容忍;两种替代标志同时存在时 ALT_LIMITS_2 优先。非纵向的 0x4F1 只允许 controls_allowed 时 Resume,或 cruise_engaged_prev 时 Cancel;纵向模式跳过整个按钮 TX 分支,白名单内的 0x4F1 不受该专属按钮码限制,这是插件权限设计必须额外收紧的差异。

    纵向加速度 0x421 同时核对 aReqRaw 与 aReqValue,单位是 0.01 m/s²,活动范围为 -350 到 200,并禁止 AEB 减速度命令、AEB 请求和停止请求。共享加速度检查允许未激活编码,不能仅用数值落在范围内推断准入。雷达 SCC 纵向表包含 0x38D FCA11,专属钩子禁止其减速度/AEB 激活字段;0x483 FCA12 仅有地址/总线/长度白名单;0x7D0 仅雷达 SCC 纵向可发送,载荷必须是 02 3E 80 00 00 00 00 00。SCC11/13/14、FRT_RADAR11 和 HUD 没有该模式的逐字段校验,白名单准入不代表 ECU 接受,也不代表原车 AEB、FCW 或仪表状态保持不变。

    面向自制硬件的插件契约

    源文档给出的是一组建议设计而非已实现能力:车型身份插件应输出带证据的标准/Legacy、SCC 来源、动力类型与转向限制,未知或冲突组合不授予 TX;总线插件同时报告 RX/TX 的物理接口与本地 bus,尤其记录相机 SCC 模式下按钮 RX bus 0、TX bus 2 的差异。

    纵向插件只能提交控制意图;可信任网关需核对构建类型、MCU mode/param 读回、ECU 静默回执、原车 AEB 功能与失联降级,再交由独立 MCU safety 门裁决。对纵向 CLU11、FCA12、HUD 与 SCC 附属帧应另设最小载荷模板和速率配额,不能因原模式白名单存在就向普通插件开放原始 CAN 写入。现有 test_hyundai.py 覆盖标准/Legacy、替代转向限值、相机 SCC、FCEV 与纵向 AEB/诊断路径,但本文未运行这些单测,模型实体、目标固件、台架及实车行为仍未验证。

    常见问题

    Hyundai Legacy 模式是不做 RX 校验吗?

    不是。Legacy 只放宽 0x386 和 0x394 的校验与计数检查;0x260、0x4F1、0x421 仍保留各自的校验或计数门。同时它强制关闭纵向和相机 SCC。

    相机 SCC 模式下按钮输入在哪个总线?

    按钮 RX 仍是 bus 0,只是 CLU11 的 TX 落在 bus 2。源码明确说明不能把 TX 所在总线误当成按钮输入来源。

    Hyundai 纵向控制是不是打开参数就能用?

    不是。LONG 仅在 ALLOW_DEBUG 编译条件下有效,共享 hyundai_common_init() 在非调试构建中强制关闭纵向。Python 侧 CarParams 位不能作为量产固件可发的证明。

    0x7D0 的载荷能自由填吗?

    不能。源文档说明 0x7D0 仅雷达 SCC 纵向可发送,载荷必须是固定的 02 3E 80 00 00 00 00 00。

    延伸阅读

    参考资料

    • 项目 02 —— openpilot-research/HYUNDAI_CLASSIC_PANDA_SAFETY_DEEP_DIVE.md(模式权限矩阵、RX 完整性表、TX 字段边界与插件契约)。
    • 项目 02 —— openpilot-research/ 同目录 Hyundai/Honda 品牌总览(SCC 与纵向能力作为相邻边界参考)。

    说明:本文为对固定源码快照的静态结构分析,未运行完整测试套件、未连接硬件、未验证目标车型的真实参数组合。文中所有阈值、行号索引与配置均出自源文档,标注为未验证的结论保留其原有边界。

    更新记录

    首次发布 2026-10-11 最近核对:2026-10-11

  • Hyundai 控制输出:经典 CAN 与 CAN FD 两条构帧路径与独立安全门

    结论:Hyundai 的控制输出不是一条「转向命令」链路,而是同一份车型控制器代码按经典 CAN / CAN FD、原车纵向 / 自控纵向、LKA / LFA 架构分支,形成不同候选帧,再交给 panda 固件的 hyundai_tx_hook 或 hyundai_canfd_tx_hook 独立复核。主机侧 CANPacker 编码成功、CarOutput.accel 回报正确、tester-present 发出,都不等于 ECU 接受。下述节拍以 card 目标 100 Hz 且每轮调用一次控制器为前提,是代码名义节拍,不是实测总线频率。

    公共控制周期:力矩、加速度与请求位

    每一控制轮,CarController.update() 先把 actuators.torque 乘以车型 STEER_MAX,再以最近一次软件输出和 CS.out.steeringTorque 调用驾驶员力矩/变化率限制。横向未活动时力矩清零;经典 CAN 分支在横向活动但请求位被切断时还会设置 torque_fault,CAN FD 分支没有这个额外字段。这是两条分支在同一控制器里的第一处实现差异。

    common_fault_avoidance() 在转角绝对值达到 85 度时管理请求位,目的在于避免 EPS 长时间大角度带扭矩故障。加速度只做 [-3.5, 2.0] m/s² 夹限,再传给具体纵向报文;CarOutput 回报的 accel 就是这一软件夹限值,不是 CAN FD 内部 aReqValue、MCU 发送回执或车辆实测加速度。

    诊断保活方面,若启用 openpilot 纵向且非 CANFD_CAMERA_SCC,每 100 帧向经典 CAN 雷达 0x7d0、CAN FD E-CAN 雷达 0x7d0 或 LKA 架构 ADAS ECU 0x730 形成一条 tester-present 候选。它的目的是维持此前请求的 ECU 静默,不能证明 ECU 已静默;CarInterface.init() 使用通用 disable_ecu(),其成功/失败返回值没有被 card.ControlsReady 闭环消费。取消请求持续时 cancel_counter 逐轮加一,解除请求即归零——源码注释指出部分车辆的取消键也可能是暂停/恢复键,因此原车纵向的按钮取消被延迟。

    经典 CAN 输出:LKAS11 与 SCC 家族

    LKAS11 每控制轮形成候选:继承 CS.lkas11 中一批原车相机字段,覆盖转向力矩、请求位、HUD 警告、车道线和计数,再按车型选择 CRC8、前 6 字节和、或前 6+末字节和三种校验之一。它不是泛用的「转向命令」结构,不同车型的显示字段也有例外,process_hud_alert() 对部分 Genesis 警告采用不同编码。原车纵向下,持续取消超过 10 帧后发送一条 CLU11 取消候选;恢复请求则在距上次按钮帧大于 0.1 秒时一次追加 25 个相同恢复候选,而 last_button_frame 只在间隔至少 0.15 秒时更新。

    自控纵向每偶数帧形成 SCC11、SCC12、SCC14;USE_FCA 且非 CAMERA_SCC 时还生成 FCA11。SCC12 的 aReqRaw / aReqValue 都取软件加速度,计数器及 nibble checksum 由构帧函数处理;SCC14 传入 jerk 上限和 HUD 前车状态。非 FCA 路径在 SCC12 设置 AEB disabled 字段,FCA 路径在 FCA11 设置相应禁用状态。

    经典 CAN 报文 触发条件与节拍 关键边界
    LKAS11 每控制轮 覆盖力矩/请求位/HUD;校验方式按车型三分支
    CLU11 取消 原车纵向且持续取消超过 10 帧 「最多 10 Hz」注释不等于严格上限
    恢复候选 ×25 距上次按钮帧 > 0.1 秒 不构成 25 条 ECU 接受证明
    SCC11 / SCC12 / SCC14 自控纵向每偶数帧 SCC12 双加速度字段;SCC14 传 jerk 与前车状态
    FCA11 USE_FCA 且非 CAMERA_SCC 设置制动执行禁用状态
    SCC13 / FCA12 5 Hz 选项帧 额外选项帧,非原车 AEB 保留保证
    FRT_RADAR11 2 Hz 选项帧 同上,单独验证
    LFA 图标 SEND_LFA 平台每 5 帧 仅图标候选

    经典 panda hook 对 LKAS11 限扭矩/请求位,对 SCC12 检查两路加速度并禁止 AEB 执行字段,对 FCA11 阻止制动执行位;诊断地址只允许固定 tester-present 载荷。不同 hyundai、hyundaiLegacy、相机 SCC 和纵向模式选择不同 RX 检查与 TX 白名单,软件字段编码正确仍可能被 MCU 拒绝。

    CAN FD 输出:LKA/LFA 路由与 SCC_CONTROL

    CanBus 按 LKA/LFA 转向架构决定 A-CAN 或 E-CAN。LKA 平台生成 LKAS / LKAS_ALT,仅在自控纵向时同时补 LFA,其他平台直接生成 LFA。LKA 平台每 5 帧还用最近缓存的 CAM_0x2a4 / CAM_0x362 字段构造「无车道线」报文来抑制原车 LFA——这属于 ADAS 能力修改,应单独验证缓存年龄与原车功能影响。图标候选按 LKA/纵向组合每 5 帧输出;若 flag 开启,LKA 平台可生成 SPAS1 / SPAS2 转向灯候选。

    自控纵向每偶数帧生成一条 SCC_CONTROL:aReqRaw 用夹限后的目标,aReqValue 用与上次记录 accel_last 相差不超过 5/50 的值;accel_last 随后记录当前原始目标,而不是编码出的 aReqValue。所以这个运算不能简单称为持续的输出速率限制,阶跃目标须回放核对两个字段和 ECU 响应。LKA 架构另发 ADRV 系列报文以配合禁用 ADAS ECU,LFA 架构按偶数帧生成 AEB disabled 图标报文。

    CAN FD 路径 生成条件 需单独验证的点
    LKAS / LKAS_ALT LKA 架构每轮 总线归属(A-CAN/E-CAN)
    LFA 自控纵向补发,或非 LKA 平台直接生成 架构判定是否正确
    无车道线抑制报文 LKA 平台每 5 帧 缓存 CAM 报文年龄、原车功能影响
    SCC_CONTROL 自控纵向每偶数帧 aReqRaw 与 aReqValue 的 5/50 差值语义
    ADRV 系列 LKA 架构 与禁用 ADAS ECU 的配合
    AEB disabled 图标 LFA 架构每偶数帧 仅图标,不等于 AEB 状态
    SPAS1 / SPAS2 flag 开启且 LKA 平台 本快照未见设置该 flag 的车型

    原车纵向 CAN FD 用按钮或 SCC_CONTROL 取消:备用按钮平台直接复用最近 CS.cruise_info 的计数/校验及状态字段,把 ACCMode 改为 4、加速度置零;标准按钮平台须取消持续超过 10 帧、距上次按钮超过 0.25 秒,才一次追加 20 个相同的取消按钮候选。标准按钮的恢复也可一次追加 20 个候选;备用按钮平台的恢复分支只是 pass,本快照未实现。MCU safety 仍要求原车纵向 SCC_CONTROL 为取消模式且加速度为零。

    插件化与硬件验收边界

    把转向、纵向、巡航按钮、HUD、ADAS 抑制和诊断保活声明为不同能力,各自绑定平台、DBC、线束、节拍及安全模式,是这套实现的自然结论。车型控制插件只提交结构化候选;唯一受信任网关验证 CAN 地址、物理总线、长度、年龄、限幅和 ECU 静默状态,并由独立 MCU 保留不可绕过的 TX safety。禁止把 CANPacker 成功、CarOutput 回报或 tester-present 发送等同于 ECU 接受。

    无车验证应覆盖经典 CAN/CAN FD、LKA/LFA、原车/自控纵向、相机 SCC、备用按钮、AEB 图标、缓存断流、大转角请求位、加速度阶跃和诊断失效,再逐帧与 DBC、panda hook 对照。CANFD_ENABLE_BLINKERS 还存在对 0x7b1 的保活及 SPAS 构帧代码,但本快照静态平台表未见设置该 flag 的车型,不能把代码分支当成已启用的实车能力。

    常见问题

    为什么 CAN FD 里的 aReqValue 不能当作真实加速度限幅?

    因为 SCC_CONTROL 的 aReqValue 取的是与上次记录 accel_last 相差不超过 5/50 的值,而 accel_last 记录的是当前原始目标而非编码结果。这个运算在阶跃目标下不是持续速率限制,须回放核对两字段与 ECU 响应;CarOutput 回报的 accel 也只是软件夹限值,不是车辆实测加速度。

    tester-present 发出去,是否说明雷达 ECU 已被静默?

    不代表。每 100 帧形成的 tester-present 候选只用于维持此前请求的 ECU 静默状态,本身不能证明 ECU 已进入静默;CarInterface.init() 使用的 disable_ecu() 返回值也没有被 card.ControlsReady 闭环消费,因此不能由「帧已构造」推断「ECU 已接受」。

    经典 CAN 与 CAN FD 的转向输出差在哪?

    经典 CAN 每控制轮形成 LKAS11,并在横向活动但请求位被切断时设置 torque_fault;CAN FD 按 LKA/LFA 架构生成 LKAS/LKAS_ALT 或 LFA,没有这个额外字段。此外 CAN FD 的 LKA 平台还会每 5 帧构造「无车道线」报文抑制原车 LFA,属于 ADAS 能力修改。

    备用按钮平台的恢复功能是否已实现?

    未实现。源文档明确:原车纵向 CAN FD 中,标准按钮平台的恢复可一次追加 20 个候选,而备用按钮平台的恢复分支只是 pass,本快照未实现。取消分支则复用最近 CS.cruise_info 的字段并把 ACCMode 改为 4、加速度置零。

    延伸阅读

    参考资料

    • 项目 02 —— openpilot-research/HYUNDAI_CONTROLLER_CAN_OUTPUT_DEEP_DIVE.md(取用了公共控制周期、经典 CAN 与 CAN FD 构帧节拍、panda hook 复核点与插件化边界)。
    • 项目 02 —— openpilot-research/CAR_PROTOCOL_IMPLEMENTATIONS.md(仅用于确认 Hyundai 品牌目录与 CAN/CAN FD 链路的总体位置)。

    说明:本文为对固定源码快照的静态结构分析,未运行完整测试套件、未连接硬件、未验证目标车型的真实参数组合。文中所有阈值、行号索引与配置均出自源文档,标注为未验证的结论保留其原有边界。

    更新记录

    首次发布 2026-10-11 最近核对:2026-10-11