# Motion 安全检查设计稿

## 1. 目标

围绕 [`MainShell/Motion/SafeAxisMotion.cs`](MainShell/Motion/SafeAxisMotion.cs) 、 [`MainShell/Motion/MotionController.cs`](MainShell/Motion/MotionController.cs) 与 [`MainShell/Motion/StagePlatformMotionService.cs`](MainShell/Motion/StagePlatformMotionService.cs) 建立一套统一的运动前安全检查方案，在不破坏现有分层的前提下，为后续代码实现提供明确设计依据。

本设计稿目标如下：

- 所有真实运动入口具备统一前置安全检查能力
- 单轴底线检查 设备级互锁检查 机构专属检查边界清晰
- 多轴联动在下发前完成组合安全判定
- 失败处理方式统一，包括阻断 联停 告警 日志
- 为后续切换到 `code` 模式提供实现蓝图

---

## 2. 当前代码结构观察

### 2.1 现有职责

当前主要调用链如下：

- [`StagePlatformMotionService.MovePlaneAsync()`](MainShell/Motion/StagePlatformMotionService.cs:37)
- [`SafeAxisMotion.SafeMoveAsync()`](MainShell/Motion/SafeAxisMotion.cs:56)
- [`SafeAxisMotion.MoveAbsInternalAsync()`](MainShell/Motion/SafeAxisMotion.cs:222)
- [`MotionController.MoveAbsAsync()`](MainShell/Motion/MotionController.cs:34)

当前各层职责已经基本成形：

| 层级 | 当前职责 | 对应文件 |
|---|---|---|
| 机构动作层 | 组织业务动作 组装联动请求 | [`MainShell/Motion/StagePlatformMotionService.cs`](MainShell/Motion/StagePlatformMotionService.cs) |
| 安全运动调度层 | 统一封装单轴 多轴运动 失败联停 告警上报 | [`MainShell/Motion/SafeAxisMotion.cs`](MainShell/Motion/SafeAxisMotion.cs) |
| 轴控制层 | 下发运动命令 轴状态校验 软限位检查 超时控制 | [`MainShell/Motion/MotionController.cs`](MainShell/Motion/MotionController.cs) |
| 参数速度层 | 速度参数应用 | [`MainShell/Motion/AxisSpeedManager.cs`](MainShell/Motion/AxisSpeedManager.cs) |

### 2.2 当前已有安全基础

现有代码中已经具备一些底层安全能力：

- [`MotionController.ValidateMotionState()`](MainShell/Motion/MotionController.cs:218)
- [`MotionController.EnsureWithinSoftLimit()`](MainShell/Motion/MotionController.cs:242)
- [`MotionController.ValidateTimeout()`](MainShell/Motion/MotionController.cs:257)
- [`SafeAxisMotion.CancelAndStopRelatedAxes()`](MainShell/Motion/SafeAxisMotion.cs:405)

说明当前系统并不是没有安全设计，而是**还缺少统一的运动前安全检查编排层**。

---

## 3. 设计原则

### 3.1 分层原则

- 只依赖单轴自身状态的规则，放在 [`MotionController`](MainShell/Motion/MotionController.cs)
- 依赖整机状态或多个硬件对象的规则，放在 [`SafeAxisMotion`](MainShell/Motion/SafeAxisMotion.cs)
- 只对某个业务动作成立的规则，放在机构服务层，例如 [`StagePlatformMotionService`](MainShell/Motion/StagePlatformMotionService.cs)

### 3.2 收口原则

所有真实发运动命令的入口，后续应尽可能统一经过：

- [`SafeAxisMotion.MoveAbsAsync()`](MainShell/Motion/SafeAxisMotion.cs:153)
- [`SafeAxisMotion.MoveRelAsync()`](MainShell/Motion/SafeAxisMotion.cs:163)
- [`SafeAxisMotion.SafeMoveAsync()`](MainShell/Motion/SafeAxisMotion.cs:56)
- [`SafeAxisMotion.HomeAsync()`](MainShell/Motion/SafeAxisMotion.cs:209)

### 3.3 组合判定优先原则

多轴动作必须先整体检查，再启动任意一根轴，避免出现部分轴已开始移动、剩余轴检查失败的情况。

### 3.4 检查结果结构化原则

后续检查结果不应只返回 true 或 false，而应具备规则名、层级、失败原因、影响轴、是否报警、恢复建议等结构化信息。

---

## 4. 安全检查分层方案

## 4.1 第一层 轴级底线检查

### 定位

用于保证单轴命令发出前的最低安全边界，不承载设备业务语义。

### 放置位置

- [`MainShell/Motion/MotionController.cs`](MainShell/Motion/MotionController.cs)

### 检查项

| 检查项 | 说明 | 当前状态 |
|---|---|---|
| 轴对象存在 | 防止空引用和未初始化轴 | 已部分具备 |
| Axis.State 可用 | 保证状态读取有效 | 已具备 |
| Servo 已上电 | 禁止断使能运动 | 已具备 |
| 无 ALM ServoFault EMG | 禁止故障状态运动 | 已具备 |
| CanMove 为 true | 禁止当前状态不允许运动 | 已具备 |
| 目标在软限位内 | 防止目标超行程 | 已具备 |
| 超时参数合法 | 防止非法等待参数 | 已具备 |
| 驱动返回码正常 | 命令下发失败立即阻断 | 已具备 |

### 不建议放入的规则

- 安全门
- 总急停整机状态
- 气缸或相机回避
- 多轴组合碰撞
- 流程阶段判断
- 自动手动模式权限

这些都超出了单轴控制器边界。

---

## 4.2 第二层 设备级互锁检查

### 定位

这是后续“每次运动前统一安全检查”的核心层。

### 放置位置

建议以后仍然由 [`SafeAxisMotion`](MainShell/Motion/SafeAxisMotion.cs) 作为总入口，但将检查逻辑进一步抽象为专门组件，例如：

- `MotionSafetyChecker`
- `IMotionSafetyPolicy`
- `IMotionPrecheck`
- `MotionInterlockService`

### 典型检查项

| 检查项 | 说明 | 建议失败处理 |
|---|---|---|
| 总急停已释放 | 整机急停未复位时禁止运动 | 阻断 + 可报警 |
| 安全门状态允许 | 门打开时禁止危险动作 | 阻断 + 可报警 |
| 当前模式允许该动作 | 自动 手动 调试权限控制 | 阻断 |
| 当前流程状态允许运动 | 防止流程中非法插入动作 | 阻断 |
| 关键气缸在安全位 | 防止机构干涉 | 阻断 + 可报警 |
| 真空 夹持 吸附状态满足要求 | 防止掉料 空跑 | 阻断 |
| 危险机构已退出 | 防止碰撞 | 阻断 + 可报警 |
| 同组互斥对象未占用 | 防止并发冲突 | 阻断 |
| 当前速度模式满足安全约束 | 危险段使用安全速度 | 阻断或降级 |

### 设计要求

- 必须在真正调用 [`MotionController.MoveAbsAsync()`](MainShell/Motion/MotionController.cs:34) 前完成
- 应支持单轴与多轴动作共用
- 应支持和报警系统集成
- 应支持基于模式和场景动态组合规则

---

## 4.3 第三层 多轴组合检查

### 定位

用于解决单轴单独都合法，但组合动作整体不安全的问题。

### 放置位置

优先放在 [`SafeAxisMotion.SafeMoveAsync()`](MainShell/Motion/SafeAxisMotion.cs:56) 所在层。

对于明显属于某机构专属姿态约束的规则，也可先由机构服务层做第一轮检查。

### 典型检查项

| 检查项 | 说明 | 建议归属 |
|---|---|---|
| 多轴请求中无重复轴 | 防止一个批次对同一轴下多个目标 | 安全运动层 |
| 多轴组合目标整体可达 | 防止单轴都合法但整体姿态不合法 | 安全运动层 |
| 多轴目标不引发机械碰撞 | 防止联动过程干涉 | 安全运动层 |
| 联动姿态变化量不超限 | 防止平台受力异常或姿态突变 | 机构层或安全运动层 |
| 是否需要先中转位再联动 | 防止直接走位不安全 | 机构层 |

### 重点建议

[`StagePlatformMotionService.MovePlaneAsync()`](MainShell/Motion/StagePlatformMotionService.cs:37) 这类三轴联动动作，后续一定要先做整体姿态检查，再交给 [`SafeAxisMotion.SafeMoveAsync()`](MainShell/Motion/SafeAxisMotion.cs:56) 发命令。

---

## 4.4 第四层 机构工艺检查

### 定位

只对某类业务动作成立的前置条件，不应做成全局通用规则。

### 放置位置

- [`MainShell/Motion/StagePlatformMotionService.cs`](MainShell/Motion/StagePlatformMotionService.cs)
- 未来其他机构服务

### 典型检查项

| 检查项 | 说明 |
|---|---|
| 平台三点高度差不超限 | 防止平台姿态异常 |
| 平移前已抬安全高度 | 防止横移干涉 |
| 对位前光学条件准备完成 | 防止动作无效 |
| BondHead 或相机已回避 | 防止机构碰撞 |
| 顶针 吸嘴 工装在安全位 | 防止治具干涉 |
| 当前工艺阶段允许该动作 | 保证流程一致性 |
| 工件状态正确 | 防止空跑 掉料 误动作 |

---

## 5. 推荐调用链方案

```mermaid
flowchart TD
    A[业务动作入口] --> B[机构服务前置检查]
    B --> C[统一安全运动入口]
    C --> D[构建运动检查上下文]
    D --> E[设备级互锁检查]
    E --> F[多轴组合检查]
    F --> G[单轴底线检查]
    G --> H[下发运动命令]
    H --> I[等待完成 取消 超时]
    I --> J[失败联停 告警 日志]
```

### 5.1 业务动作入口

例如：

- [`StagePlatformMotionService.MovePlaneAsync()`](MainShell/Motion/StagePlatformMotionService.cs:37)

职责：

- 表达动作意图
- 先做机构专属前置条件判断
- 组装单轴或多轴请求
- 调用统一安全运动入口

### 5.2 统一安全运动入口

例如：

- [`SafeAxisMotion.SafeMoveAsync()`](MainShell/Motion/SafeAxisMotion.cs:56)
- [`SafeAxisMotion.MoveAbsAsync()`](MainShell/Motion/SafeAxisMotion.cs:153)
- [`SafeAxisMotion.MoveRelAsync()`](MainShell/Motion/SafeAxisMotion.cs:163)
- [`SafeAxisMotion.HomeAsync()`](MainShell/Motion/SafeAxisMotion.cs:209)

职责：

- 解析请求
- 构建上下文
- 执行设备级与组合级前置检查
- 通过后调用 [`MotionController`](MainShell/Motion/MotionController.cs)
- 失败时统一联停 告警 日志

### 5.3 单轴命令执行入口

例如：

- [`MotionController.MoveAbsAsync()`](MainShell/Motion/MotionController.cs:34)
- [`MotionController.MoveRelAsync()`](MainShell/Motion/MotionController.cs:50)
- [`MotionController.HomeAsync()`](MainShell/Motion/MotionController.cs:130)

职责：

- 轴底线校验
- 下发命令
- 超时与取消控制
- 返回结构化结果

---

## 6. 推荐检查执行顺序

建议后续严格固定顺序，避免规则散落。

### 步骤 1 机构动作前置检查

适用于业务动作服务，例如平台动作先检查：

- 是否需要先走安全高度
- 目标姿态是否合法
- 当前流程状态是否允许

### 步骤 2 设备级互锁检查

统一检查：

- 总急停
- 安全门
- 关键气缸
- 回避状态
- 模式权限
- 关键资源占用

### 步骤 3 多轴组合检查

统一检查：

- 多轴目标是否冲突
- 联动是否越界
- 是否需要分步走位
- 是否存在组合干涉

### 步骤 4 单轴底线检查

由 [`MotionController`](MainShell/Motion/MotionController.cs) 执行：

- Servo
- Alarm
- CanMove
- 软限位
- 超时与驱动返回码

### 步骤 5 发命令与结果收敛

调用底层轴执行，并在失败时统一：

- 联停
- 告警
- 日志记录

---

## 7. 建议的数据模型

本节不是要求立刻编码，而是后续实现时建议统一抽象。

## 7.1 运动检查上下文

建议未来形成类似 `MotionCheckContext` 的概念，字段建议包括：

| 字段 | 说明 |
|---|---|
| Operation | MoveAbs MoveRel Home Jog |
| Axis | 当前目标轴 |
| AxisName | 轴名称 |
| CurrentPosition | 当前位 |
| TargetPosition | 目标位 |
| Distance | 相对位移 |
| RelatedAxes | 关联轴集合 |
| Requests | 当前批量请求 |
| Mode | 自动 手动 调试 |
| Source | 调用来源或动作名 |
| NeedAlarm | 是否需要报警 |
| TimeoutMilliseconds | 超时配置 |

## 7.2 检查结果模型

建议未来形成类似 `MotionCheckResult` 的概念。

| 字段 | 说明 |
|---|---|
| IsPassed | 是否通过 |
| RuleName | 规则名称 |
| Layer | 规则所属层级 |
| Severity | Block 或 Warning |
| Message | 失败描述 |
| AxisNames | 影响轴 |
| AlarmId | 可选报警编号 |
| RecoveryHint | 建议恢复方式 |

## 7.3 检查规则接口方向

建议未来每条规则抽象成统一接口，例如：

- `IMotionPrecheck`
- `IMotionSafetyRule`

每条规则只负责一件事，统一输入上下文，统一输出结果。

---

## 8. 失败处理策略

后续所有安全检查与运动失败，建议统一为三类处理级别。

| 级别 | 说明 | 典型场景 |
|---|---|---|
| Block | 阻断但不联停 | 发命令前检查失败 |
| StopAndBlock | 先停止相关轴再阻断 | 多轴动作中途失败 |
| AlarmAndBlock | 报警并阻断 | 急停 门禁 危险机构未回避 |

结合现有能力：

- 联停可复用 [`SafeAxisMotion.CancelAndStopRelatedAxes()`](MainShell/Motion/SafeAxisMotion.cs:405)
- 报警可复用 [`SafeAxisMotion.ReportAlarmAsync()`](MainShell/Motion/SafeAxisMotion.cs:379)
- 日志可复用 [`HandleMotionStarted()`](MainShell/Motion/SafeAxisMotion.cs:346) 与 [`HandleMotionFinished()`](MainShell/Motion/SafeAxisMotion.cs:358)

---

## 9. 对当前各文件的未来职责建议

## 9.1 [`MainShell/Motion/MotionController.cs`](MainShell/Motion/MotionController.cs)

### 保持职责

- 单轴命令执行
- 底线安全检查
- 超时控制
- 结果封装

### 不建议新增

- 安全门判断
- 气缸互锁判断
- 工艺流程阶段判断
- 平台姿态判断
- 多轴组合碰撞判断

## 9.2 [`MainShell/Motion/SafeAxisMotion.cs`](MainShell/Motion/SafeAxisMotion.cs)

### 强化为统一前置安全入口

未来建议增加：

- 前置检查编排
- 单轴与多轴统一安全上下文构建
- 设备级互锁检查
- 多轴组合检查
- 失败等级处理策略

### 保持现有优势

- 单轴与多轴入口已经集中
- 已具备联停能力
- 已具备报警对接能力
- 已具备日志挂接点

## 9.3 [`MainShell/Motion/StagePlatformMotionService.cs`](MainShell/Motion/StagePlatformMotionService.cs)

### 保留机构业务语义

未来建议这里承担：

- 平台类动作专属规则
- 姿态约束
- 安全中转位策略
- 业务前置条件

而不是直接下沉到轴控制层。

## 9.4 [`MainShell/Motion/AxisSpeedManager.cs`](MainShell/Motion/AxisSpeedManager.cs)

### 可扩展为安全速度策略辅助层

例如未来用于：

- 危险区动作自动切安全速度
- 根据模式切换速度模板
- 高风险动作限制加速度和 jerk

但它不应承担互锁判断主责。

---

## 10. 分阶段实施计划

## 阶段 A 规则清单固化

先在设计层确认：

- 哪些规则为全局必检
- 哪些规则为机构专属
- 哪些规则为阻断型
- 哪些规则为报警型
- 哪些规则仅提示

## 阶段 B 入口收口检查

确认项目内是否存在绕过 [`SafeAxisMotion`](MainShell/Motion/SafeAxisMotion.cs) 直接调用轴对象的路径。

如果有，后续应逐步迁移，避免统一检查失效。

## 阶段 C 上下文模型抽象

统一后续所有检查的输入对象，避免每条规则自行拼接所需数据。

## 阶段 D 先实现高价值规则

优先顺序建议：

1. 总急停
2. 安全门
3. Servo 和 Alarm
4. 软限位
5. 危险机构回避
6. 多轴组合越界

## 阶段 E 再补机构专属规则

例如：

- 平台三点姿态约束
- 安全高度
- 中转位策略
- 工装占位状态

---

## 11. 需要优先确认的规则清单

后续若进入详细实现设计，建议优先由业务方或设备调试方确认以下问题：

| 主题 | 需要确认的问题 |
|---|---|
| 急停 | 是否整机任何运动都必须检查总急停 |
| 安全门 | 手动模式是否允许门开点动 |
| 模式权限 | 自动 手动 调试的运动权限边界 |
| 危险区 | 哪些机构组合构成机械干涉 |
| 平台联动 | Z7 Z8 Z9 姿态变化允许范围 |
| 中转位 | 哪些动作必须先走安全位再到目标位 |
| 报警策略 | 哪些检查失败必须报警 哪些只阻断 |
| 速度策略 | 哪些动作需要强制安全速度 |

这些内容越早明确，后续实现越稳定。

---

## 12. 最终设计结论

本设计稿的结论如下：

1. [`MotionController`](MainShell/Motion/MotionController.cs) 继续承担单轴底线检查与命令执行职责
2. [`SafeAxisMotion`](MainShell/Motion/SafeAxisMotion.cs) 应演进为统一的运动前安全检查编排入口
3. 多轴联动必须先做组合安全检查，再统一下发命令
4. [`StagePlatformMotionService`](MainShell/Motion/StagePlatformMotionService.cs) 这类机构服务负责工艺专属前置条件
5. [`AxisSpeedManager`](MainShell/Motion/AxisSpeedManager.cs:22) 可作为安全速度策略辅助组件，但不承载主互锁逻辑
6. 后续实现宜采用 规则接口 + 上下文对象 + 分层编排 的方式推进，而不是在各处零散追加 if 判断

该方案兼顾了现有代码结构、现场可维护性与后续扩展性，适合作为下一阶段实现设计的基础文档。
