You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
LightWork3D/docs/FreeCAD 3D自动布线设计方案.md

516 lines
12 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# FreeCAD 3D 自动布线设计方案
本文档描述 QET / LightWork3D 与 FreeCAD 协同中的 3D 自动布线设计。
当前版本目标不是完整复刻 EPLAN Pro Panel 或 SOLIDWORKS Electrical而是先完成一个可用的最小闭环
```text
工程端子
-> 路由路径网络
-> 自动求路
-> 生成 3D 折线导线
-> 可保存到 FreeCAD 文档
```
## 1. 设计边界
### 1.1 当前版本目标
当前版本只要求完成“能够自动布线”:
1. 能识别 FreeCAD 文档中的工程端子。
2. 能从用户指定的线槽、草图、面域创建路由网络。
3. 能在两个端子之间自动生成 3D 折线导线。
4. 能批量处理 QET 导入的导线任务。
5. 能绕开或至少发现明显障碍碰撞。
6. 默认禁止长距离悬空线。
### 1.2 当前版本不做
当前版本不做以下工程级能力:
1. 不修改 FreeCAD C++ 源码。
2. 不写入或依赖旧 3D 场景数据库表。
3. 不把 3D 位姿、3D 路径点写入数据库。
4. 不做完整线槽容量计算。
5. 不做线径、弯曲半径、线束层叠排列。
6. 不做强弱电隔离、EMC、屏蔽线等电气规则。
7. 不保证达到 EPLAN / SOLIDWORKS Electrical 的完整工程级自动布线效果。
### 1.3 数据库约束
第一版严格遵守 `docs/数据库设计.md`
1. 设备绑定只依赖:
```text
project_2d3d_symbol_binding:
project_uuid
element_uuid
instance_id
```
2. 端子绑定只依赖:
```text
project_2d3d_terminal_binding:
project_uuid
terminal_uuid
instance_id
```
3. 3D 端子绑定唯一依据是:
```text
terminal_uuid
```
4. 3D 位姿、装配关系、布线几何以 FreeCAD 文档为准。
## 2. 总体方案
自动布线不直接在任意 3D 空间里找线,也不会把所有端子任意两两连接。它参考 EPLAN / SOLIDWORKS 的思路,先建立“可走路径网络”,再按 QET 导线任务中的起点端子和终点端子逐条求路。
```text
端子出线段
-> 进入最近路由节点
-> 在线槽/路由路径网络中求最短路
-> 从路由网络出来
-> 进入目标端子
```
路由网络由 `carrier` 组成。一个 carrier 表示一段可走线中心线或辅助路由区域中的一条网格线。
### 2.1 路由优先级
当前版本按下面优先级处理:
1. `WireDuct`:线槽中心路径,最高优先级。
2. `RoutingPath`用户画的草图线、Draft Wire、明确选中的路由边。
3. `AuxiliaryPath`:辅助路径,后续扩展使用。
4. `RoutingRange`:选中面生成的辅助路由区域,成本较高,只用于过渡或没有线槽时兜底。
普通机柜、设备外壳、实体边默认不是路由路径。
## 3. FreeCAD 对象语义
### 3.1 工程端子
工程端子是可布线起点和终点,必须满足:
```text
Role = "Terminal"
CanWire = true
QetTerminalUuid = <2D terminal_uuid>
QetInstanceId = <3D instance_id>
QetProjectUuid = <project_uuid>
```
端子空间位置来自 FreeCAD 文档。自动布线使用端子的全局坐标和方向。
### 3.2 路由路径 Carrier
路由路径对象使用以下语义属性:
```text
QetRoutingRole = "RoutingCarrier"
QetRouteCarrierKind = "WireDuct" | "RoutingPath" | "AuxiliaryPath" | "RoutingRange"
CanRouteWire = true
QetProjectUuid = <project_uuid>
Points = [Vector, Vector, ...]
```
carrier 统一放在:
```text
QETWiring
02_Carriers
```
### 3.3 自动导线
自动生成的导线放在:
```text
QETWiring
04_Routed
```
自动导线语义:
```text
RouteType = "AutoSuggested"
RouteMode = "Auto"
RouteStatus = "Routed" | "CollisionWarning"
QetStartTerminalUuid
QetEndTerminalUuid
QetAutoRouteAlgorithm
QetAutoRouteDiagnosticsJson
```
### 3.4 线槽实体
当用户选择线槽实体并执行“从线槽实体生成中心路径”后:
1. 系统按包围盒长轴生成 `WireDuct` 中心路径。
2. 原线槽实体标记为可穿线路由源。
3. 碰撞检测跳过该线槽实体本身,避免“线在槽内却撞到线槽外壳”的误报。
线槽实体属性:
```text
QetRoutingSourceKind = "WireDuct"
QetRoutingObstacleMode = "PassThrough"
QetRouteCarrierName = <generated carrier name>
```
## 4. 算法设计
### 4.1 路由网络构建
模块:
```text
src/Mod/FreeCADExchange/RoutingNetwork.py
```
构建步骤:
1. 收集所有 `QetRoutingRole = RoutingCarrier` 的对象。
2. 读取 carrier 的 `Points`
3. 将相同或接近坐标的点合并为图节点。
4. 将相邻点之间的线段建立为图边。
5. 每条边记录所属 carrier用于计算路径成本。
### 4.2 最短路算法
当前使用:
```text
Dijkstra + bend_penalty
```
路径成本:
```text
edge_cost = segment_length * carrier_kind_factor + bend_penalty
```
其中:
```text
WireDuct = 1.0
RoutingPath = 1.0
AuxiliaryPath = 2.0
RoutingRange = 8.0
```
这使算法优先走线槽和明确路由路径,尽量少走辅助面域。
### 4.3 端子接入
模块:
```text
src/Mod/FreeCADExchange/AutoRouting.py
```
流程:
1. 读取起点端子和终点端子的全局坐标。
2. 按端子方向生成短出线段。
3. 找到距离起点出线点最近的路由节点。
4. 找到距离终点出线点最近的路由节点。
5. 在路由网络中执行 Dijkstra。
6. 将端子出线段、网络路径、终点入线段拼成最终折线。
当前算法名:
```text
network-dijkstra-v1
```
### 4.4 悬空线策略
当前版本默认:
```text
allow_floating_fallback = false
```
也就是说,如果没有可用路由网络,系统不会生成长距离悬空线,而是提示用户先创建线槽路径、草图路径或辅助路由区域。
调试时可以显式启用 fallback但正式使用不建议开启。
### 4.5 障碍物处理
当前版本使用 AABB 包围盒做碰撞诊断:
1. 收集 FreeCAD 文档中的几何对象。
2. 排除端子、carrier、已布线导线、原点辅助对象。
3. 排除标记为 `QetRoutingObstacleMode = PassThrough` 的线槽实体。
4. 检查导线线段是否与障碍包围盒相交。
5. 如果有碰撞,导线状态设为:
```text
RouteStatus = "CollisionWarning"
```
当前版本是“碰撞诊断”,不是完整自由空间避障。
## 5. 当前已完成
### 5.1 Python 模块
已实现:
```text
src/Mod/FreeCADExchange/RoutingNetwork.py
src/Mod/FreeCADExchange/AutoRouting.py
src/Mod/FreeCADExchange/AutoRoutingPanel.py
```
并已加入:
```text
src/Mod/FreeCADExchange/CMakeLists.txt
src/Mod/FreeCADExchange/InitGui.py
```
### 5.2 路由网络功能
已完成:
1. 从选中草图线、Draft Wire、明确选中的边创建 `RoutingPath`
2. 从选中线槽实体生成 `WireDuct` 中心路径。
3. 从选中面生成 `RoutingRange` 辅助路由区域。
4. 清除已生成路由路径。
5. 扫描并统计路由网络。
### 5.3 自动布线功能
已完成:
1. 两个选中端子之间自动布线。
2. 根据导线任务批量自动布线。
3. 使用 Dijkstra 求路。
4. 支持转弯惩罚。
5. 支持 carrier 类型成本。
6. 默认禁止长距离悬空线。
7. 碰撞检测和 `CollisionWarning` 状态。
8. 自动导线可见显示并保存到 FreeCAD 文档。
### 5.4 FreeCAD 面板
面板入口:
```text
QET模板 -> 3D自动布线
```
当前按钮:
```text
扫描端子/网络
从线槽实体生成中心路径
从线槽/草图创建路由路径
从选中面创建辅助路由区域
测试布线选中两个端子
按导线任务自动布线全部
清除自动布线
清除走线路径
保存
```
### 5.5 测试
已完成单元测试:
```text
tests/python/freecad_exchange_auto_routing_test.py
```
覆盖:
1. 无路由网络时默认拒绝悬空线。
2. 显式调试 fallback 时生成正交路径。
3. 优先使用用户路由网络。
4. 优先使用 `WireDuct`,降低 `RoutingRange` 优先级。
5. 从选中面生成辅助路由区域。
6. 选中整个实体不会把所有外壳边转成路径。
7. 从线槽实体生成中心路径。
8. 线槽实体不作为自身路径碰撞障碍。
9. 碰撞状态标记。
10. 批量导线任务缺端子时跳过。
11. 清除路由路径不删除已布线导线。
已完成 FreeCAD smoke
```text
tests/manual/freecad_auto_routing_smoke.py
```
## 6. 当前使用流程
### 6.1 单条导线自动布线
```text
1. 打开 FreeCAD 工程 scene.FCStd
2. 进入 QET模板 -> 3D自动布线
3. 清除走线路径
4. 选中线槽实体
5. 点击“从线槽实体生成中心路径”
6. 必要时选草图线或 Draft Wire点击“从线槽/草图创建路由路径”
7. 必要时选背板/门板面,点击“从选中面创建辅助路由区域”
8. 选中两个工程端子
9. 点击“测试布线选中两个端子”
```
### 6.2 批量导线自动布线
前提:
1. QET 导出的 `2d_to_3d.json` 中包含 `wires[]`
2. 每条导线包含:
```text
start_terminal_uuid
end_terminal_uuid
```
3. FreeCAD 文档中存在对应 `QetTerminalUuid` 的工程端子。
操作:
```text
1. 创建线槽/路由网络
2. 点击“按导线任务自动布线全部”
```
注意:批量自动布线的依据是导线任务,不是“所有端子自动互连”。如果文档中只有端子而没有 `wires[]``QETWiring_01_Tasks`,系统不能判断哪些端子应该连接。
## 7. 当前限制
当前版本可完成自动布线原型,但仍有以下限制:
1. 线槽实体中心线生成基于包围盒长轴,不理解真实线槽开口、盖板和内部空间。
2. 多根线会沿同一路径生成,暂未做并行错位排列。
3. 未计算线槽填充率和容量。
4. 未考虑线径、最小弯曲半径。
5. 未做强弱电分槽、线缆类型隔离。
6. 障碍检测基于 AABB存在误报和漏报。
7. 辅助路由区域是网格近似,不等于专业软件的完整布线区域建模。
8. 端子出线方向依赖端子 LCS 方向;如果模板端子方向不准,自动布线会受影响。
9. 导线几何当前保存在 FreeCAD 文档,不作为第一版数据库字段回写。
## 8. 后续需要完成
### 8.1 近期优先级
1. 线槽语义库
```text
WireDuct:
centerline
width
height
inlet/outlet
usable_area
cover_state
```
2. 多根线错位排列
```text
同一路径上的多根导线按 lane_offset 排列
避免完全重叠
```
3. 线槽容量和填充率
```text
按线径估算截面积
计算 duct fill ratio
超过阈值给出警告
```
4. 端子出线规则
```text
根据端子 LCS 方向、设备安装面、接线孔方向生成更合理的短出线段
```
### 8.2 中期能力
1. 真实几何碰撞检测
从 AABB 升级到更精确的 Shape / BRep 碰撞检测,降低误报。
2. 弯曲半径约束
根据线缆类型和线径控制转弯半径。
3. 线束对象
把多根同路导线抽象成 bundle并支持展开显示。
4. 规则约束
支持:
```text
强电 / 弱电隔离
PE 线优先路径
屏蔽线规则
不同电压等级分槽
禁布区域
```
5. 更智能的线槽识别
根据对象名称、尺寸比例、设备库语义自动识别线槽,而不完全依赖用户选择。
### 8.3 长期能力
1. 接近 EPLAN / SOLIDWORKS 的工程级路由器。
2. 完整导线长度统计。
3. 自动生成线束报表。
4. 2D / 3D 导线一致性校验。
5. 自动推荐线槽路径和线槽容量。
6. 多柜体、多门板、多安装板之间的跨区域路由。
7. 可视化布线诊断面板。
## 9. 验收标准
当前版本验收只看“能否自动布线”:
1. 文档中有至少两个工程端子。
2. 文档中有至少一条 `WireDuct``RoutingPath` carrier。
3. 选择两个端子后执行单线测试布线,能生成 `AutoSuggested` 导线。
4. 存在导线任务时执行“按导线任务自动布线全部”,能批量生成 `AutoSuggested` 导线。
5. 生成导线在 `QETWiring_04_Routed` 下可见。
6. 没有路由网络时不生成长距离悬空线。
7. 没有导线任务时,批量布线明确提示缺少连接关系。
8. 明显碰撞时状态为 `CollisionWarning`
9. 保存 FreeCAD 文档后,自动导线和路由网络仍保留。
## 10. 开发验证命令
单元测试:
```powershell
D:\FreeCAD-1.1.1\bin\python.exe -m unittest discover -s tests\python -p "freecad_exchange*_test.py"
```
真实 FreeCAD smoke
```powershell
D:\FreeCAD-1.1.1\bin\python.exe tests\manual\freecad_auto_routing_smoke.py
```
语法检查:
```powershell
D:\FreeCAD-1.1.1\bin\python.exe -m py_compile src\Mod\FreeCADExchange\AutoRouting.py src\Mod\FreeCADExchange\RoutingNetwork.py src\Mod\FreeCADExchange\AutoRoutingPanel.py
```