# 01-项目功能内容

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

## 1. 总体需求

以 ABB IRB120 3/58 的 URDF fixture 为真实 6 轴工业机器人基准，构建一套端到端全面测试能力：

1. 编写通用机器人语言 GRL 测试程序，覆盖运动、路径、IO、等待、工艺、报警和异常。
2. 在项目运行时加载 ABB120 URDF，执行 FK、IK、Jacobian、限位、轨迹规划、虚拟控制器运行和调试。
3. 将同一 GRL/IR 输出为 ABB RAPID、FANUC LS 风格和 KUKA KRL 风格程序，并生成转换报告。
4. 建立离线编程全面测试，包括资源建模、路径生成、可达性、节拍、碰撞、IO/Wait、品牌导入导出、报告和客户交付包。
5. 用 HTML 实现本项目虚拟控制器界面，对标 ABB RobotStudio 的 Station、Controller、RAPID、Simulation、Virtual FlexPendant 等工作流。
6. 补齐 GRL 运算表达式能力，覆盖 ABB、FANUC、KUKA 三类机器人语言共同具备的算术、比较、逻辑和常用数学函数，并能在运动参数编译期求值。

## 2. ABB120 URDF 基准

基准机器人来自 `/home/meswork/kdl_work/kdl-wasm/web/tests/fixtures/abbIrb120.ts` 中的 `ABB_IRB120_3_58_URDF`。

| 项 | 值 |
| --- | --- |
| robotId | `abb_irb120_3_58` |
| baseLink | `base_link` |
| tipLink | `tool0` |
| DOF | 6 |
| active joints | `joint_1` 到 `joint_6` |
| fixed links | `base`、`flange`、`tool0` |
| URDF 来源 | ROS-Industrial ABB IRB120 3/58 xacro 派生，当前 fixture 省略 mesh、material、inertial、xacro-only 元素 |

关节限位以 fixture 为准：

| 关节 | lower rad | upper rad | velocity rad/s |
| --- | ---: | ---: | ---: |
| `joint_1` | -2.87979 | 2.87979 | 4.36332 |
| `joint_2` | -1.91986 | 1.91986 | 4.36332 |
| `joint_3` | -1.91986 | 1.22173 | 4.36332 |
| `joint_4` | -2.79253 | 2.79253 | 5.58505 |
| `joint_5` | -2.094395 | 2.094395 | 5.58505 |
| `joint_6` | -6.98132 | 6.98132 | 7.33038 |

标准测试关节位：

| 名称 | rad |
| --- | --- |
| `home` | `[0, 0, 0, 0, 0, 0]` |
| `pick` | `[0.2, -0.35, 0.45, 0.1, -0.2, 0.3]` |
| `place` | `[-0.35, -0.25, 0.35, -0.25, 0.15, -0.4]` |
| `approach` | `[0, -0.4, 0.5, 0, 0.2, 0]` |

## 3. 通用机器人测试程序集

测试程序以 GRL 为主，命名建议为 `A120_XX_*.grl`。所有程序必须能解析为 AST、编译为 Semantic IR、进入 KDL bridge，并保留 source map。

### 3.1 `A120_00_Smoke.grl`

目标：最小链路冒烟测试。

覆盖点：

1. 语言头、module、speed、zone、target。
2. `movej home`。
3. FK、限位检查、轨迹规划和 ABB 后处理。

验收：程序运行完成，无 error diagnostic；ABB/FANUC/KUKA 输出均非空。

### 3.2 `A120_10_JointPickPlace.grl`

目标：关节空间 pick/place 主流程。

基准程序：

```grl
language grl 0.1
module A120JointPickPlace
  const speed v_fast = joint(40 %)
  const speed v_slow = joint(20 %)
  const zone z10 = z(10 mm)

  target home = joint_target { joints: [0 deg, 0 deg, 0 deg, 0 deg, 0 deg, 0 deg] }
  target approach = joint_target { joints: [0 deg, -22.918312 deg, 28.647890 deg, 0 deg, 11.459156 deg, 0 deg] }
  target pick = joint_target { joints: [11.459156 deg, -20.053523 deg, 25.783101 deg, 5.729578 deg, -11.459156 deg, 17.188734 deg] }
  target place = joint_target { joints: [-20.053523 deg, -14.323945 deg, 20.053523 deg, -14.323945 deg, 8.594367 deg, -22.918312 deg] }

  path pick_place {
    defaults { speed: v_fast, zone: z10 }
    point p_home movej home zone fine
    point p_approach movej approach
    event before p_pick io.do[1] = true
    point p_pick movej pick speed v_slow zone fine
    point p_place movej place
    event after p_place io.do[1] = false
  }

  proc main()
    run_path pick_place
  end
end
```

验收：`planPath` 产生 4 段 MOVEJ，终点关节等于 `place`，IO 事件进入 trace。

### 3.3 `A120_20_CartesianBlend.grl`

目标：笛卡尔运动和 blend 规则测试。

覆盖点：

1. 由 `home/pick/place` FK 自动生成 reachable pose targets。
2. `movel` 接近点、工件点和离开点。
3. `movec` 中间点和终点。
4. `zone fine` 与 `z(10 mm)` 对比。

验收：每个 pose target 通过 IK；笛卡尔段输出最大 TCP 直线误差和圆弧误差。

### 3.4 `A120_30_IOWaitPulse.grl`

目标：IO、等待、脉冲和 timeout。

覆盖点：

1. `io.do[n] = true/false`。
2. `wait io.di[n] == true timeout 2 s`。
3. `pulse io.do[n] duration 100 ms`。
4. timeout 后 alarm 或 fallback path。
5. IO script 驱动 DI 上升沿、下降沿和 changed。

验收：虚拟控制器可显示 wait 表达式、已等待时间、剩余 timeout、相关 IO 最近变化和脚本状态。

### 3.5 `A120_40_ErrorDiagnostics.grl`

目标：故障路径和诊断稳定性。

覆盖点：

1. 超出关节限位目标。
2. 明确不可达 pose target。
3. 奇异姿态或接近奇异姿态。
4. 未定义 target/path/operation。
5. wait timeout。

验收：每类故障都有稳定 code、severity、source map 和报告条目。

### 3.6 `A120_50_OperationProcess.grl`

目标：工艺 operation 和离线编程对象闭环。

覆盖点：

1. `path`、`operation`、`run_operation`。
2. start/end action，如夹爪、吹气、扫码、视觉等待。
3. 工艺参数进入报告和交付包。
4. OLP 对象模型可反向生成 GRL。

验收：`operation` 展开为 action + path + action，报告包含工艺步骤、节拍和 IO 事件。

## 4. GRL 运算功能需求

目标：将“运算功能”作为 GRL 语言和语义基础能力补齐，而不是只让 parser 能读。首版按 ABB RAPID、FANUC LS/KAREL、KUKA KRL 的公共数学子集建模，保证同一 GRL 程序可以稳定编译到统一 IR，再由后处理器输出三品牌程序。

### 4.1 语法范围

GRL 表达式必须支持：

1. 算术：一元 `+`、一元 `-`、`+`、`-`、`*`、`/`、`mod`。
2. 比较：`==`、`!=`、`<`、`<=`、`>`、`>=`。
3. 逻辑：`and`、`or`、`not`，可兼容 `&&`、`||`、`!` 作为输入别名，IR 中统一为 GRL 关键字。
4. 括号：`(...)` 明确优先级。
5. 函数调用：沿用当前 `callee(args...)` 形式。
6. 现有结构表达式：array、object、call、identifier、offset 表达式必须继续兼容。

优先级从高到低：

| 层级 | 运算 |
| --- | --- |
| 1 | 函数调用、对象、数组、括号、offset |
| 2 | 一元 `+`、`-`、`not`、`!` |
| 3 | `*`、`/`、`mod` |
| 4 | `+`、`-` |
| 5 | `<`、`<=`、`>`、`>=` |
| 6 | `==`、`!=` |
| 7 | `and`、`&&` |
| 8 | `or`、`||` |

### 4.2 函数和常量

首版内置常量：

| 名称 | 含义 |
| --- | --- |
| `pi` | 圆周率 |
| `e` | 自然常数 |

首版内置函数：

| 类别 | 函数 |
| --- | --- |
| 三角函数 | `sin`、`cos`、`tan`、`asin`、`acos`、`atan`、`atan2` |
| 数值函数 | `sqrt`、`abs`、`pow`、`min`、`max`、`clamp`、`floor`、`ceil`、`round` |

三角函数语义：

1. `sin/cos/tan` 接收角度量；带 `deg` 或 `rad` 单位时归一化为弧度，纯数按弧度处理。
2. `asin/acos/atan/atan2` 返回角度量；在 `pose(...)` 姿态项或 `joint_target.joints` 等角度上下文中可直接使用。
3. 函数必须做定义域检查，例如 `sqrt(-1)`、`acos(2)` 必须产生 diagnostic。

### 4.3 编译期求值位置

常量表达式必须在编译阶段求值，并把结果写入 Semantic IR / KDL request，而不是把表达式字符串传到运动规划层。

必须支持的求值位置：

1. 数据声明 initializer：`const`、`persistent`、需要静态初值的 `var`。
2. `speed`：`linear(...)`、`joint(...)`、`acc ...` 参数。
3. `zone`：`fine`、`z(...)`、`cnt(...)`。
4. `pose(...)`、`poseq(...)`、`robot_config(...)`。
5. `joint_target { joints: [...] }`。
6. `pose_target { pose: ... }`。
7. `tool { tcp: ..., mass: ... }`。
8. `frame { origin: ... }`。
9. path defaults/source 属性。
10. path point 内联 `speed`、`zone`、`tool`、`frame`、`via`、`target` 参数。
11. path event 的 `distance`。
12. `wait ... timeout ...` 和 `pulse ... duration ...` 中的时间常量。
13. operation process 中需要数值常量的工艺参数。

比较和逻辑表达式也必须进入 AST。纯常量比较/逻辑可在编译期折叠；依赖 IO、变量或运行态状态的条件先保留为结构化控制表达式，供虚拟控制器和后续品牌映射使用。

### 4.4 单位和数值语义

数值求值采用统一 SI 归一化：

| GRL 输入 | IR/KDL 归一化 |
| --- | --- |
| `mm` | m |
| `mm/s` | m/s |
| `mm/s2` | m/s2 |
| `deg` | rad |
| `rad` | rad |
| `%` | 0 到 1 的比例 |
| `s` | s |
| `ms` | s |
| `kg` | kg |

规则：

1. 同维度数值可以相加、相减，结果保留该维度并归一化。
2. 纯数可以参与乘除；维度乘除首版只允许编译器明确支持的上下文，避免产生复杂复合单位。
3. 不同维度相加或比较必须报错，例如 `10 mm + 2 s`。
4. 构造器可以提供默认上下文单位：`linear(...)` 默认 `mm/s`，`z(...)` 默认 `mm`，`pose(...)` 前三项默认 `mm`、后三项默认 `deg`，`joint_target.joints` 默认 `deg`，`duration/timeout` 默认 `s`。
5. 因此 `linear(100 + 50 mm/s)` 在 `linear` 速度上下文中等价于 `linear(150 mm/s)`；推荐生成器输出时使用显式单位，减少人工歧义。

### 4.5 示例

```grl
language grl 0.1
module MathMotion
  const num blend_base = 5 + 5
  const speed v_pick = linear(100 + 50 mm/s)
  const speed v_safe = linear(max(50 mm/s, 200 mm/s / 2))
  const zone z_app = z(clamp(blend_base mm, 1 mm, 50 mm))

  target home = joint_target {
    joints: [0 deg, (10 + 5) deg, -90 deg, 0 deg, 0 deg, 0 deg]
  }
  target pick = pose_target {
    pose: pose(400 + 50 mm, 20 * 2 mm, sqrt(90000) mm, 0 deg, 0 deg, atan2(1, 1))
  }

  path main_path {
    defaults { speed: v_pick, zone: z_app }
    point p0 movej home speed linear(100 + 50 mm/s) zone z(clamp(8 mm, 1 mm, 20 mm))
    point p1 movel pick
  }
end
```

编译期结果要求：

1. `v_pick` 进入 IR 后为 `linear`，速度 `0.15 m/s`。
2. `z_app` 进入 IR 后为 `distance`，距离 `0.01 m`。
3. `home.joints[1]` 进入 IR 后为 `15 deg` 对应的弧度值。
4. `pick.pose.position[0]` 进入 IR 后为 `0.45 m`。
5. path point 内联 speed/zone 同样求值后进入 KDL request。

### 4.6 诊断需求

运算功能必须输出稳定 diagnostic：

| code | 场景 |
| --- | --- |
| `GRL_EXPR_PARSE` | 表达式语法错误或括号不匹配。 |
| `GRL_EXPR_UNKNOWN_SYMBOL` | 常量求值遇到未知标识符。 |
| `GRL_EXPR_UNKNOWN_FUNCTION` | 未知函数。 |
| `GRL_EXPR_ARITY` | 函数参数数量错误。 |
| `GRL_EXPR_DOMAIN` | 数学定义域错误。 |
| `GRL_EXPR_DIV_ZERO` | 除零。 |
| `GRL_EXPR_UNIT_MISMATCH` | 单位维度不兼容。 |
| `GRL_EXPR_NON_CONSTANT` | 需要常量的位置出现运行时表达式。 |
| `GRL_EXPR_UNSUPPORTED_RUNTIME` | 后续品牌映射暂不支持的复杂运行时表达式。 |

每个 diagnostic 必须包含 severity、message、source range，并能通过 source map 定位到 GRL 源文件行列。

### 4.7 跨品牌边界

首版跨品牌输出不直接翻译复杂表达式字符串，而是优先输出编译期折叠后的常量：

1. `linear(100 + 50 mm/s)` 输出为各品牌可表达的具体速度值。
2. `z(clamp(...))` 输出为具体 ABB zone、FANUC CNT 或 KUKA 近似 blend。
3. runtime 条件表达式如果后处理器无法保真映射，必须进入转换报告，不得静默丢失。
4. 品牌专用数学函数或控制器变量不作为首版目标，后续通过 post/import report 增量支持。

## 5. 程序运行需求

运行器必须支持以下流程：

1. 加载 ABB120 URDF fixture，生成 `NormalizedRobotModel` 和 RobotHandle。
2. 编译 GRL：Lexer、Parser、Semantic Analyzer、IR、source map。
3. 对每个 target/path/operation 生成 KDL request。
4. 执行 KDL：FK、fkAllLinks、Jacobian、IK、limit、singularity、planMoveJ、planMoveL、planMoveC、planPath、validatePath。
5. 执行虚拟控制器：load、run、pause、step、stop、reset、breakpoint、motion queue、IO、wait、pulse、trace。
6. 输出结构化 job：`job_id`、输入文件、运行参数、诊断、轨迹、trace、报告、截图路径。

## 6. 跨品牌程序转换需求

同一 Semantic IR 必须输出：

| 品牌 | 输出文件 | 核心指令 |
| --- | --- | --- |
| ABB | `.mod` | `MoveJ`、`MoveL`、`MoveC`、`SetDO`、`WaitUntil`、`PulseDO` |
| FANUC | `.ls` | `J`、`L`、`C`、`DO[]`、`WAIT`、`PULSE` |
| KUKA | `.src`，必要时 `.dat` | `PTP`、`LIN`、`CIRC`、`$OUT[]`、`WAIT FOR` |

转换报告必须记录：

1. 速度、zone、tool、frame 映射。
2. 近似语义，如 ABB zone 到 FANUC CNT、KUKA C_DIS。
3. 不支持语义，如复杂 trap、多任务、品牌专用工艺包。
4. source map：GRL 行列、path point、operation、品牌输出行号。
5. 回读校验：品牌文本重新导入后，target/path/motion 顺序与原 IR 等价或输出差异报告。

## 7. 离线编程全面测试需求

全面测试必须覆盖：

1. 项目建模：Station、Robot、Tool、Frame、Target、Path、Operation、Program、Report。
2. 工作区：OPFS-like 保存、bundle 导入导出、损坏检测、迁移。
3. 几何和路径：点、边、曲线生成 Path；路径采样和姿态策略。
4. 可达性：单点、批量、路径段、operation。
5. 轨迹：节拍、速度、加速度、采样、重采样、blend 近似。
6. 碰撞：机器人自身、工具、工件、夹具、禁入区的基础碰撞时间点。
7. IO/Wait：脚本、timeout、边沿、trace、报告。
8. 品牌链路：GRL 到三品牌、三品牌导入、交叉品牌再导出。
9. 客户交付：源程序、品牌程序、IO map、校准数据、报告 HTML/PDF、trace、截图。
10. 自动化证据：命令输出、job JSON、report JSON、HTML 页面、截图、PDF。

## 8. HTML 虚拟控制器需求

### 8.1 对标范围

对标 ABB RobotStudio 的工作方式，而不是复制视觉资产。公开参考资料包括 ABB RobotStudio Suite 官方页面和 RobotStudio Operating Manual 2026.2。参考点：

1. Station / Graphics：机器人、工具、工件、路径和碰撞对象。
2. Controller：虚拟控制器状态、RobotWare/robot model 信息、权限和运行控制。
3. RAPID / Program Editor：程序树、模块、当前行、诊断、断点。
4. Simulation：播放、暂停、单步、重置、速度倍率、时间轴。
5. Virtual FlexPendant：模式、Motors On、PP to Main、Start、Stop、Hold、Jog、IO、Alarms。

### 8.2 页面信息架构

首屏必须直接进入工程工作台，不做营销页。

建议 HTML 布局：

1. 顶部命令栏：项目、导入、保存、运行、暂停、停止、单步、导出报告。
2. 左侧对象树：Station、Robot、Tool、Frame、Target、Path、Operation、Program、Reports。
3. 中央工作区：3D/2D station viewport、路径轨迹、机器人姿态、碰撞和选中对象。
4. 右侧虚拟示教器：状态灯、模式、关节/TCP、Jog、速度倍率、程序指针、报警。
5. 底部面板：日志、诊断、IO、Wait、Motion Queue、Trace、报告。
6. 编辑区：GRL/RAPID/FANUC/KUKA 多标签查看，source map 双向定位。

### 8.3 交互需求

1. 加载 ABB120 测试项目后，页面显示机器人模型、程序树和默认 `main` 程序。
2. 点击 Run 后，虚拟控制器状态变化，程序指针、motion queue、IO trace 和时间轴同步更新。
3. 点击 Step 时执行单条 IR 指令。
4. 点击 path point 时，编辑器跳转 GRL source map，3D/2D viewport 高亮目标。
5. wait 卡住时，右侧面板显示 wait 条件、当前子表达式值、相关 IO 最近变化、timeout 倒计时和手动置位动作。
6. 后处理导出后，ABB/FANUC/KUKA 代码可在标签页查看并下载。
7. 报告页可打开 HTML 报告，并能导出 PDF 或打印。

### 8.4 技术边界

1. 首版可以是 HTML + CSS + TypeScript 的静态工作台页面，接入现有 facade 和 runtime。
2. 3D 视图可先使用简化连杆模型；如果引入 Three.js，应验证桌面和移动视口截图非空、机器人正确入框。
3. 不承诺复刻 ABB RobotStudio 的真实 RobotWare、完整 RAPID 解释器、真实安全系统、真实控制器通信。
4. 不复制 ABB 商标、图标、界面皮肤或专有资源。

## 9. 非目标

1. 不以 FANUC 二进制 TP 为首版输入。
2. 不实现完整 CAD kernel。
3. 不实现品牌控制器 look-ahead 完全复刻。
4. 不将浏览器虚拟控制器声明为真实机器人安全控制器。
5. 不绕过 ABB、FANUC、KUKA 的真实控制器安全、权限和认证流程。
