3.7 KiB
场景回放模式下机器人状态图标不显示问题修复文档
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函数。在该函数的最开始,增加一段逻辑:- 检查当前机器人图元的
visible属性。 - 如果
visible为false,则立即、强制地调用一次this.ctx.setValue({ id, visible: true }, ...),将其设置为true。 - 无论检查结果如何,后续逻辑都假定机器人是可见的。
- 检查当前机器人图元的
-
效果:此修改从根本上解决了问题。它确保了无论上游的状态同步有多大延迟,只要准备渲染图标,机器人图元本身一定会被置为可见状态,从而保证了图标的正确渲染。
5. 总结
本次修复的核心在于通过层层调试,最终定位到底层库在特定场景下的时序问题,并采用在消费端强制同步状态的策略,绕过了这一底层限制,最终稳健地解决了问题。