web-map/docs/fixes/playback-robot-icon-fix.md

50 lines
3.7 KiB
Markdown
Raw Normal View History

# 场景回放模式下机器人状态图标不显示问题修复文档
## 1. 问题背景
在系统的场景回放Playback模式下机器人的“不接单”、“充电中”等状态图标无法正常显示。尽管机器人的位置可以随时间回放而正确移动但附加的状态图标始终不可见。此问题在实时Live模式下不存在。
## 2. 问题分析与调试过程
### 初步分析
- **现象对比**:实时模式下图标显示正常,回放模式异常。这表明问题很可能出在两种模式处理机器人数据和状态更新的逻辑差异上。
- **代码定位**
- 实时模式逻辑主要位于 `src/pages/movement-supervision.vue`
- 回放模式逻辑主要位于 `src/hooks/usePlaybackWebSocket.ts`
- 状态图标的渲染逻辑由 `src/services/editor/editor-robot.service.ts` 中的 `updateRobotStatusOverlay` 函数负责。
### 第一次尝试:对齐数据更新逻辑
通过对比代码发现,回放模式下的 `batchUpdateRobots` 函数在更新机器人图元Pen没有像实时模式那样明确地将 `visible` 属性设置为 `true`
- **修复操作**:修改 `usePlaybackWebSocket.ts`,在 `editor.setValue` 调用中,为机器人图元添加 `visible: true` 属性。
- **结果**:问题依旧。通过添加的日志发现,尽管 `usePlaybackWebSocket.ts` 发送了 `visible: true` 的更新指令,但在下游的 `editor-robot.service.ts` 中检查时,图元的 `visible` 属性仍然是 `false`
### 第二次尝试:解决时序问题
日志表明,`setValue` 的调用和 `updateRobotStatusOverlay` 的调用之间存在时序问题Timing Issue`setValue` 的更新不是立即同步的,导致后续的 `updateRobotStatusOverlay` 读取到了旧的、未更新的 `visible` 状态。
- **修复操作**:调整 `usePlaybackWebSocket.ts``batchUpdateRobots` 的执行顺序。将 `updateRobotStatusOverlay` 的调用移至所有 `setValue` 批量执行**之后**,确保在更新图标时,图元属性已经生效。
- **结果**:问题仍然存在。日志显示,即使调整了执行顺序,`meta2d` 底层库的状态同步似乎仍然存在延迟,`visible` 属性的更新未能及时反映。
## 3. 根本原因定位
经过两轮失败的尝试,根本原因被确定为:**`meta2d` 核心库在回放模式这种高频、批量数据更新的场景下,存在内部状态更新不及时或失败的问题**。
上层应用的修复(如调整调用顺序)无法完全规避这个底层问题。无论上游如何正确地发送指令,下游在读取状态时都可能拿到旧数据。
## 4. 最终解决方案:强制状态同步
既然无法保证状态能被上游正确同步,最终的解决方案是在状态消费的最后一环——即渲染图标之前,进行强制检查和同步。
- **修复操作**:修改 `src/services/editor/editor-robot.service.ts` 中的 `updateRobotStatusOverlay` 函数。在该函数的最开始,增加一段逻辑:
1. 检查当前机器人图元的 `visible` 属性。
2. 如果 `visible``false`,则立即、强制地调用一次 `this.ctx.setValue({ id, visible: true }, ...)`,将其设置为 `true`
3. 无论检查结果如何,后续逻辑都假定机器人是可见的。
- **效果**:此修改从根本上解决了问题。它确保了无论上游的状态同步有多大延迟,只要准备渲染图标,机器人图元本身一定会被置为可见状态,从而保证了图标的正确渲染。
## 5. 总结
本次修复的核心在于通过层层调试,最终定位到底层库在特定场景下的时序问题,并采用在消费端强制同步状态的策略,绕过了这一底层限制,最终稳健地解决了问题。