# 06-决策记录

版本：0.3  
日期：2026-06-27

## ADR-001：`working1` 只对标两份源文档

状态：Accepted  
日期：2026-06-27  
关联任务：`KW-000`

### 背景

用户要求 `/home/meswork/kdl_work/work/working1` 内实施文档完全对标：

1. `/home/meswork/kdl_work/work/doc/KDL_WASM计算接口设计.md`
2. `/home/meswork/kdl_work/work/doc/通用机器人编程语法规范.md`

### 决策

`working1` 的范围只从这两份文档抽取。其他技术方案不作为本目录任务、验收和 ADR 的来源。

### 后果

1. 任务分为 KDL WASM 计算接口线和 GRL 编程语法线。
2. OPFS、UI、虚拟控制器和碰撞检测等内容不单独展开，除非两份源文档明确作为工程结构、调用关系、后处理或测试项出现。
3. 所有 P0/P1 以两份源文档的实施优先级为准。

## ADR-002：KDL WASM 是 GRL 的运动计算内核，不解释 GRL

状态：Accepted  
日期：2026-06-27  
关联任务：`KW-001` 到 `KW-013`、`KW-103` 到 `KW-110`

### 背景

KDL WASM 接口设计明确规定 KDL 不负责 GRL 词法语法解析、流程控制、变量、IO、wait、子程序调用、碰撞检测和 OPFS 项目文件管理。

### 决策

KDL WASM 只接收已经由 TypeScript 编译层解析完成的模型、目标点、速度、zone、tool、frame 和 motion request。

### 后果

1. `movej/movel/movec/run_path` 编译后调用 KDL。
2. `if/for/switch/call/wait/io/alarm` 不直接调用 KDL。
3. `operation.process` 不进入 KDL，TypeScript 只把 operation 展开的 motion segment 交给 KDL。

## ADR-003：GRL AST、语义检查、IR 和 KDL request 分层实现

状态：Accepted  
日期：2026-06-27  
关联任务：`KW-100` 到 `KW-110`

### 背景

GRL 语法规范定义的编译管线为：

```text
GRL Source -> Lexer -> Parser -> AST -> Symbol Table -> Semantic Analyzer -> Executable IR -> Virtual Controller -> Post Processor
```

KDL 接口设计要求 GRL 编译器把 `movej/movel/movec` 解析为 IR 后，由虚拟控制器调用 KDL 函数。

### 决策

实现中明确区分：

1. AST：保留语法结构、source range、单位原文和品牌 metadata。
2. Semantic Analyzer：完成类型、单位、名称、路径、operation、IO 和运动语义检查。
3. IR：作为虚拟控制器和后处理的统一输入。
4. KDL request：只由运动 IR、Path IR 派生。

### 后果

1. KDL API 不依赖 GRL AST。
2. 后处理不直接消费 KDL 轨迹点，而是优先消费 IR、目标点和品牌 profile。
3. source map 必须贯穿 AST、IR、KDL request 和诊断。

## ADR-004：机器人结构以 URDF 为源数据，TypeScript 生成标准模型

状态：Accepted  
日期：2026-06-27  
关联任务：`KW-002`

### 背景

KDL 接口设计规定机器人结构源数据为 URDF，TypeScript 解析 XML 并生成 `NormalizedRobotModel`，WASM 根据标准模型构造 KDL `Tree/Chain`。

### 决策

实现 `loadRobotFromUrdf` 时，TypeScript 负责：

1. 解析 URDF XML。
2. 检查 link/joint 连通性和单位。
3. 生成 `NormalizedRobotModel`。

WASM 负责：

1. 从 `NormalizedRobotModel` 构造 KDL Chain。
2. 创建 FK、IK、Jacobian solver。
3. 返回 `RobotHandle`。

### 后果

1. `NormalizedRobotModel` schema 是 TypeScript 与 WASM 的稳定边界。
2. GRL 编译器在编译 `joint_target` 时按 `RobotInfo.dof` 检查长度。
3. WASM 仍需对模型做防御性校验并返回 `KDL_INVALID_MODEL`。

## ADR-005：内部统一使用 SI 单位和位置 + 四元数位姿

状态：Accepted  
日期：2026-06-27  
关联任务：`KW-006`、`KW-100`、`KW-102`

### 背景

GRL 支持 `mm`、`deg`、`mm/s` 等带单位字面量。KDL 接口设计要求内部位姿统一为位置 + 四元数。

### 决策

1. GRL lexer/parser 保留单位原文。
2. 语义层将单位规范化为 SI。
3. `pose()` 在编译层转换为四元数。
4. `poseq()` 四元数必须归一化。
5. KDL API 只接收规范化后的 `Pose`。

### 后果

1. 所有后处理时再按品牌格式转换。
2. 单位错误在 GRL 语义检查阶段报告。
3. 位姿数值约定由 KDL `normalizePose/composePose/inversePose` 测试固定。

## ADR-006：P0 zone 只保留语义并近似为 fine

状态：Accepted  
日期：2026-06-27  
关联任务：`KW-008` 到 `KW-011`、`KW-111`

### 背景

KDL 接口设计写明首版 `zone` 可只用于诊断和后处理，运动规划先按 `fine` 到点执行，P1 再实现连续 blend。

### 决策

P0 中 `ZoneSpec` 必须保留在 IR、KDL request、TrajectoryResult 和后处理中。KDL 轨迹规划按 `fine` 到点执行，并返回 `KDL_ZONE_APPROXIMATED` warning。

### 后果

1. P0 轨迹不声称复现品牌控制器连续过渡。
2. 后处理仍可输出 ABB `zonedata`、FANUC `CNT`、KUKA `C_DIS` 等语义。
3. P1 再实现 `planBlendPath` 或等价连续过渡。

## ADR-007：所有 KDL API 返回结构化诊断

状态：Accepted  
日期：2026-06-27  
关联任务：`KW-001` 到 `KW-013`

### 背景

KDL 接口设计要求所有 API 不抛裸字符串错误，必须返回结构化错误和诊断。

### 决策

KDL Worker RPC 错误统一为：

```ts
interface KdlError {
  code: string;
  message: string;
  diagnostics: MotionDiagnostic[];
}
```

KDL 诊断固定包含：

1. `KDL_INVALID_MODEL`
2. `KDL_TARGET_UNREACHABLE`
3. `KDL_IK_FAILED`
4. `KDL_JOINT_LIMIT`
5. `KDL_VELOCITY_LIMIT`
6. `KDL_ACCEL_LIMIT`
7. `KDL_SINGULARITY`
8. `KDL_ARC_DEGENERATE`
9. `KDL_PATH_EMPTY`
10. `KDL_ZONE_APPROXIMATED`

### 后果

1. 自动测试断言诊断 code，不依赖 message 文本。
2. sourceMap 必须随诊断传递。
3. 后处理和报告可区分 error、warning、info。

## ADR-008：Worker RPC 是 KDL TypeScript API 的唯一调用入口

状态：Accepted  
日期：2026-06-27  
关联任务：`KW-001`、`KW-013`

### 背景

KDL 接口设计要求 KDL WASM 运行在 Worker 中，避免阻塞 UI 主线程，并要求大数组使用 Transferable 或共享内存策略。

### 决策

主线程或 GRL 编译/运行层只调用 `KdlWorkerClient`。C ABI / Embind 仅在 Worker 内封装。

### 后果

1. 所有 KDL API 为 Promise 风格。
2. Worker 崩溃和初始化失败必须可恢复。
3. 高频轨迹和批量 IK/FK 优先在 Worker 内整段计算，减少跨线程往返。

## ADR-009：KDL 底层导出稳定 C ABI / Embind 包装

状态：Accepted  
日期：2026-06-27  
关联任务：`KW-013`

### 背景

KDL 接口设计不建议把 KDL C++ 类完整暴露给 TypeScript，而是通过稳定函数导出。

### 决策

P0 底层导出以 C ABI 为基准：

1. `kdl_init`
2. `kdl_create_robot`
3. `kdl_destroy_robot`
4. `kdl_get_robot_info`
5. `kdl_fk`
6. `kdl_fk_all_links`
7. `kdl_jacobian`
8. `kdl_ik`
9. `kdl_plan_movej`
10. `kdl_plan_movel`
11. `kdl_plan_movec`
12. `kdl_plan_path`
13. `kdl_sample_trap`
14. `kdl_last_error`

TypeScript API 在 Worker 内包装这些函数，向上暴露 `KdlWasmApi`。

### 后果

1. C++ 对象生命周期不泄漏到 TypeScript 业务层。
2. 高频接口可增加 TypedArray 版本。
3. C ABI 返回码和 `kdl_last_error` 必须有测试。

## ADR-010：GRL P0 严格按语法规范第 24 章实现

状态：Accepted  
日期：2026-06-27  
关联任务：`KW-100` 到 `KW-112`

### 背景

GRL 语法规范第 24 章明确列出 P0 和 P1。

### 决策

GRL P0 必须覆盖：

1. language/module/proc。
2. const/var/persistent。
3. tool/frame/speed/zone。
4. joint_target/pose_target。
5. movej/movel/movec。
6. path/point/event/run_path。
7. operation/run_operation。
8. if/elseif/else/while/for/switch。
9. call/return/break/continue。
10. proc 参数方向。
11. func 和返回值检查。
12. io.do/di、wait、pulse。
13. AST、语义检查、IR、source map。
14. ABB、FANUC、KUKA 后处理原型。

### 后果

1. label/jump、trap/interrupt、多任务、完整品牌导入等 P1 内容不得阻塞 P0。
2. 但 P1 语法若已解析，未实现语义必须有明确诊断。

## ADR-011：后处理以 GRL IR 为输入，必须保留品牌差异报告

状态：Accepted  
日期：2026-06-27  
关联任务：`KW-111`

### 背景

GRL 语法规范要求 GRL 可转换为 ABB RAPID、FANUC LS/TP 风格文本和 KUKA KRL，并要求无法支持的品牌扩展进入转换报告。

### 决策

后处理器以 GRL IR、目标点、tool/frame、speed/zone 和 post profile 为输入。`post_hint` 和 `@brand.*` 只影响指定品牌。

### 后果

1. 不支持语义不能静默丢失。
2. 后处理 golden file 必须覆盖运动、目标点、工具、坐标系、速度、zone、IO 和 wait。
3. 转换报告是后处理验收的一部分。

## ADR-012：自动生成 GRL 优先生成 target/path/operation

状态：Accepted  
日期：2026-06-27  
关联任务：`KW-112`

### 背景

GRL 语法规范第 18 章要求自动生成程序优先生成 `target`、`path`、`operation`，不要直接把大量运动语句塞进 `proc main()`。

### 决策

GRL Generator 的默认输出为结构化对象风格：

1. 目标点命名稳定。
2. 路径点命名稳定。
3. 路径整体参数放入 `defaults`。
4. 单点差异写在 point 上。
5. CAD 或工艺来源写入 `source`。
6. 支持 compact 和 expanded 两种输出。

### 后果

1. 同一输入重复生成结果必须一致。
2. 生成文本必须可 diff。
3. 生成后必须能解析回等价对象和 IR。
