【免费下载链接】KiCadRoutingTools
A set of Python/Rust tools to aid routing in KiCad
KiCadRoutingTools 是 KiCad 的 PCB 自动布线辅助工具集,它的高速差分对布线引擎用位姿A*(Pose-based A*)搜索中轴线,再由 P/N 两条走线从中轴线垂直偏移生成——一次布线,天然保证 P/N完美平行、间隙一致。本文结合项目文档与源码,拆解这套算法如何做到"平行且等长"。
差分对为什么必须"完美平行"
高速信号(LVDS、USB、MIPI、以太网)靠 P/N 两路电压差传输。只要两路走线出现缝隙忽大忽小、长度差(skew),就会带来:
- 阻抗抖动:耦合间隙变化 → 差分阻抗不稳定 → 反射
- 串扰增大:P/N 不平行时对外辐射增强,还更容易被邻近网络耦合
- skew 超标:两条线长度差直接转化为时序误差
手工在 KiCad 里画几十对差分对,靠的是"目测平行 + 手动画蛇形"。KiCadRoutingTools 的思路则完全不同:先算一条理想中轴线,P 和 N 只是它的两条平行副本。中轴线平行度 100%,副本自然 100% 平行。
位姿A*的核心思想:每一步都带着"朝向"
普通 A* 把每个搜索点记为(x, y),走线到了焊盘旁边却可能以任意角度扎进去,路径还会充满小碎步。位姿A* 把状态扩展为四元组:
状态空间 = (x, y, θ, layer),其中 θ 离散为 8 个方向(45° 间隔)
也就是说,路由器不仅知道"走到哪",还知道"此刻车头朝向"。这让布线结果满足三个关键性质:
- 从源头出发时,沿 stub 方向直行(顺着引脚引出的方向走)
- 到达目标端时,从正确方向接入焊盘
- 转向平滑,严格遵守最小转弯半径,不会出现锯齿
算法由 Rust 实现以保证速度:pose_router.rs 实现位姿A* 主搜索,每个候选动作有三种转移——沿当前方向直行、原地转向 ±45°、打过孔换层(位置与朝向保持不变)。
Dubins 启发式:估计"还要转多远"
普通 A* 用欧氏距离当启发式,但"直线距离"完全忽略了你此刻的朝向。位姿A* 改用Dubins 路径长度作为启发式——即一辆"只能前进、有最小转弯半径"的车,从当前位姿到目标位姿的最短路径长度。
实现见 dubins.rs:穷举 6 种经典 Dubins 路径类型(LSL、RSR、LSR、RSL、RLR、LRL,即"圆-直-圆"与"圆-圆-圆"组合),取最短者。配合--min-turning-radius(默认 0.2 mm),搜索出的中轴线是符合转弯物理的平滑曲线,而不是折线锯齿。
| 普通网格A* | 位姿A* | |
|---|---|---|
| 节点状态 | (x, y) | (x, y, θ, layer) |
| 朝向 | 未知 | 8 方向 × 45° |
| 启发式 | 欧氏距离 | Dubins 路径长度 |
| 焊盘出入口角度 | 不保证 | 与 stub 方向一致 |
| 曲线质量 | 碎步多 | 平滑、受最小转弯半径约束 |
P/N 完美平行的五个步骤
完整流程写在 differential-pairs.md,核心是"中轴线 + 偏移"五步法,Python 侧主逻辑在 diff_pair_routing.py:
1️⃣ 自动识别差分对。按命名约定自动配对,覆盖_P/_N(LVDS_CLK_P)、+/-(CLK+)、DP/DM(USB)、_t/_c(DQS0_t_A)等主流风格,且只配对"同约定"的网络,避免混用命名时错配。
2️⃣ Setback 搜索发射点。中轴线不从焊盘尖端直接起飞,而是先向前退一段(--diff-pair-centerline-setback,默认 2× P-N 间距),再在逃逸方向上扫描 9 个角度(±45° 内每 11.25° 一个)找无障碍位。如果全部受阻,还会把发射方向旋转 90°/180° 再试,专门对付被密集焊盘"堵死"的端点。
3️⃣ 位姿A* 解出中轴线。搜索时中轴线携带额外净空(线宽 + 间隙) / 2,相当于把 P/N 两条线的占地一次性算进去,保证偏移后的两条线各自都离障碍物足够远。
4️⃣ 垂直偏移生成 P/N。核心函数 create_parallel_path_from_float 沿中轴线逐点做垂直偏移,偏移量正好是 P/N 中心距的一半(线宽 + 间隙) / 2。转角处用**角平分线斜接(miter)**并按2 / 角平分线长度缩放偏移(上限 3×),让 P/N 在拐角处依然保持等距——这就是"完美平行"的几何保证。
5️⃣ 换层时平行不断。差分对每换一次层要打两颗过孔(P 和 N 各一),所以算法施加了三重约束:
- 共线过孔约束:过孔前至少 2 步直行、入孔方向与来向夹角 ≤45°、出孔后先直行再允许 ±45° 转向,形成
±45° → 直行 → VIA → 直行 → ±45°的对称结构 - 过孔代价加倍:抑制无意义的换层
- GND 回流过孔:默认在每对信号过孔旁自动放置 GND 过孔(
--no-gnd-vias可关),为回流电流提供就近通路
极性不一致时(比如一端 P 在左、另一端 P 在右),路由器会尝试"翻一侧连接器"重新布线,或按--polarity-swap-nets白名单交换焊盘网络,绝不生成 P/N 交叉的铜皮。
上手:三条命令路由差分对
入口是 route_diff.py,CLI 示例:
# 基础用法:自动识别并路由所有 LVDS 差分对 python3 py_router/route_diff.py input.kicad_pcb output.kicad_pcb --nets "*lvds*" # 阻抗控制 + 对内 P/N 等长 python3 py_router/route_diff.py input.kicad_pcb output.kicad_pcb --nets "*dqs*" \ --impedance 100 --diff-pair-intra-match # 调试:中轴线与原始A*路径输出到 User.8 / User.9 python3 py_router/route_diff.py input.kicad_pcb output.kicad_pcb --nets "*lvds*" --debug-lines其中--impedance会根据板层叠结构逐层反解出线宽,保证目标差分阻抗(如 100Ω)在每层都成立。
GUI 用户打开Differential选项卡(界面源码 differential_gui.py)即可看到同样的参数:间隙、线宽、setback、转弯半径、Polarity-swap 白名单等,与 CLI 一一对应。
常用参数速查
| 参数 | 默认 | 作用 |
|---|---|---|
--diff-pair-gap | 板级 netclass 或 0.101 | P/N 间隙 (mm) |
--track-width | 板级 netclass 或 0.3 | 每条腿线宽 (mm) |
--impedance | — | 按层叠反解线宽以达到目标差分阻抗 |
--min-turning-radius | 0.2 | 位姿A* 最小转弯半径 (mm) |
--diff-pair-centerline-setback | 2× P-N 距离 | 中轴线在 stub 前方的起飞距离 |
--diff-pair-intra-match | 关 | 对内 P/N 等长匹配(给短的那条加蛇形) |
--no-gnd-vias | 关 | 禁用信号过孔旁的 GND 回流过孔 |
验证结果:不信,就量
KiCadRoutingTools 对差分对的验收不是"布完了就算赢",而是读回最终板上的真实铜皮(#1303 机制):
- 耦合长度:只有"间隙不宽于布线间隙 1.5 倍、长度 ≥ 1 个节距且占对长 ≥10%"的段才算真正耦合,否则该对会被列为
uncoupled而不是计入成功 - skew:按 KiCad 的长度测量口径计算 P/N 差,超过
--length-match-tolerance(默认 0.1 mm)时--diff-pair-intra-match会自动给短的那条加蛇形补偿,且最终判定以出货铜皮为准 - 跨对等长:多对一起匹配时见 length-matching.md,支持按传播时间(外层微带 ~5.4 ps/mm vs 内层带状线 ~6.9 ps/mm)做时间匹配
加上--debug-lines后,User.8 层画出简化中轴线、User.9 层画出原始 A* 路径,你可以亲眼看到"先有中轴线、再有 P/N"这个生成顺序。
延伸阅读
想深挖这套算法,建议按顺序读:
- docs/differential-pairs.md —— 差分对路由完整设计文档(本文的"官方详解版")
- rust_router/src/pair_search.rs —— 差分对专用搜索层(共线过孔约束所在)
- docs/configuration.md —— 全部布线配置项与层叠/阻抗选项
- docs/routing-architecture.md —— Python + Rust 混合架构总览
- docs/length-matching.md —— 组间/对内/时间三种等长匹配
一句话总结:把差分对布线拆成"解一条带朝向的中轴线 + 两次垂直偏移",用位姿A* 管住角度、用 Dubins 启发式管住转弯、用斜接偏移管住转角——平行和等长就从"画出来的结果"变成了"算法的副产品"。
【免费下载链接】KiCadRoutingTools
A set of Python/Rust tools to aid routing in KiCad
相关推荐
从零部署openpilot:300+车型支持的终极开源自动驾驶指南
从零部署openpilot:300+车型支持的终极开源自动驾驶指南 openpilot是一个功能强大的开源自动驾驶操作系统,专为机器人技术设计,目前已经能够为超
自动驾驶人工智能深度学习计算机视觉终极指南:LangExtract如何实现模糊匹配与精确定位的完美结合
终极指南:LangExtract如何实现模糊匹配与精确定位的完美结合 LangExtract是一个强大的Python库,它利用LLM从非结构化文本中提取结构化信
人工智能大模型NLPAI 应用depth-anything.cpp 相机位姿求解揭秘:DPT 头与 RANSAC 射线位姿两条路径
depth anything.cpp 相机位姿求解揭秘:DPT 头与 RANSAC 射线位姿两条路径 depth anything.cpp 是字节跳动 Dept
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考