perf(map): MapTrackerMove采用内部快路径推理#1054
Conversation
There was a problem hiding this comment.
Hey - 我在这里给出了一些高层次的反馈:
- 基于旋转的到达启发式使用了
initRot,但没有追踪初始推理是否成功,因此如果在一个片段开始时doInfer失败,那么calcDeltaRotation(targetRot, initRot)检查会悄悄地使用零值,从而可能产生误报;建议在一个表示initRot是否有效的布尔标志之后,才启用基于角度的到达条件。 - 从
ctx.RunRecognition切换到共享的mapTrackerInferRunner实例,如果MapTrackerInfer持有可变状态,可能会引入数据竞争;如果有并发调用的可能,应确保 runner 是无状态的或在内部做了同步处理,或者在每次调用时实例化一个新的 runner,而不是使用全局实例。
给 AI Agent 的提示
Please address the comments from this code review:
## Overall Comments
- The rotation-based arrival heuristic uses `initRot` without tracking whether the initial inference succeeded, so if `doInfer` fails at the start of a segment the `calcDeltaRotation(targetRot, initRot)` check will silently use the zero value and may trigger false positives; consider guarding the angle-based arrival condition behind a boolean flag that `initRot` is valid.
- Changing from `ctx.RunRecognition` to a shared `mapTrackerInferRunner` instance may introduce data races if `MapTrackerInfer` holds mutable state; if concurrent calls are possible, ensure the runner is stateless or internally synchronized, or instantiate a new runner per call instead of using a global.帮助我变得更有用!请在每条评论上点击 👍 或 👎,我会根据你的反馈改进后续的代码评审。
Original comment in English
Hey - I've left some high level feedback:
- The rotation-based arrival heuristic uses
initRotwithout tracking whether the initial inference succeeded, so ifdoInferfails at the start of a segment thecalcDeltaRotation(targetRot, initRot)check will silently use the zero value and may trigger false positives; consider guarding the angle-based arrival condition behind a boolean flag thatinitRotis valid. - Changing from
ctx.RunRecognitionto a sharedmapTrackerInferRunnerinstance may introduce data races ifMapTrackerInferholds mutable state; if concurrent calls are possible, ensure the runner is stateless or internally synchronized, or instantiate a new runner per call instead of using a global.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The rotation-based arrival heuristic uses `initRot` without tracking whether the initial inference succeeded, so if `doInfer` fails at the start of a segment the `calcDeltaRotation(targetRot, initRot)` check will silently use the zero value and may trigger false positives; consider guarding the angle-based arrival condition behind a boolean flag that `initRot` is valid.
- Changing from `ctx.RunRecognition` to a shared `mapTrackerInferRunner` instance may introduce data races if `MapTrackerInfer` holds mutable state; if concurrent calls are possible, ensure the runner is stateless or internally synchronized, or instantiate a new runner per call instead of using a global.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
Pull request overview
该 PR 为 MapTrackerMove 引入“内部快路径推理”(绕过 ctx.RunRecognition 的 Node 配置执行路径),以降低 Native 调用链路带来的延迟,并额外引入基于角度变化的“到达点位”判据与若干参数调优。
Changes:
MapTrackerMove的定位推理由ctx.RunRecognition改为直接调用MapTrackerInfer.Run(快路径)。- 新增“角度翻转”到达判据,并调整移动/推理相关参数(推理间隔、有效时间、转向速度等)。
- 调整 MapTracker 测试节点的推理精度参数。
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| assets/resource/pipeline/MapTracker.json | 提升测试节点 precision 配置,用于更高精度的推理测试输出。 |
| agent/go-service/map-tracker/move.go | 引入 doInfer 快路径、循环节奏调整、到达角度判据、旋转自适应状态更新与旋转增益细节变更。 |
| agent/go-service/map-tracker/infer.go | 新增包内单例 runner 以支撑 move.go 的快路径直接调用。 |
| agent/go-service/map-tracker/const.go | 调整时序/间隔等常量参数以配合快路径与鲁棒性优化。 |
| if dist < param.ArrivalThreshold { | ||
| log.Info().Int("x", curX).Int("y", curY).Int("index", i).Msg("Target point reached") | ||
| return true | ||
| } | ||
| if math.Abs(float64(calcDeltaRotation(targetRot, initRot))) > 90.0 { | ||
| log.Info().Int("targetRot", targetRot).Int("initRot", initRot).Int("index", i).Msg("Target point reached (guessed by rotation)") | ||
| return true |
There was a problem hiding this comment.
到达判据里用 calcDeltaRotation(targetRot, initRot) 做“角度翻转”推断时,initRot 在初始 doInfer 失败时会保持默认 0,且该推断不受距离约束:这会导致在离目标仍很远、或初始推理失败/绕路后目标方向变化较大时被误判为已到达,从而跳过路径点。建议:仅在成功获取 initRot 时启用该判据,并增加距离门槛(例如 dist 小于某个上限或明显小于 initDist)后再允许用角度翻转作为到达判断。
| if dist < param.ArrivalThreshold { | |
| log.Info().Int("x", curX).Int("y", curY).Int("index", i).Msg("Target point reached") | |
| return true | |
| } | |
| if math.Abs(float64(calcDeltaRotation(targetRot, initRot))) > 90.0 { | |
| log.Info().Int("targetRot", targetRot).Int("initRot", initRot).Int("index", i).Msg("Target point reached (guessed by rotation)") | |
| return true | |
| // 基于距离的主到达判据 | |
| if dist < param.ArrivalThreshold { | |
| log.Info(). | |
| Int("x", curX). | |
| Int("y", curY). | |
| Int("index", i). | |
| Msg("Target point reached") | |
| return true | |
| } | |
| // 仅在距离目标不算太远时,才允许通过“角度翻转”来猜测已到达,避免远距离误判 | |
| const rotationArrivalDistFactor = 3.0 | |
| if dist <= param.ArrivalThreshold*rotationArrivalDistFactor { | |
| angleDelta := math.Abs(float64(calcDeltaRotation(targetRot, initRot))) | |
| if angleDelta > 90.0 { | |
| log.Info(). | |
| Int("targetRot", targetRot). | |
| Int("initRot", initRot). | |
| Int("index", i). | |
| Float64("dist", dist). | |
| Float64("angleDelta", angleDelta). | |
| Msg("Target point reached (guessed by rotation)") | |
| return true | |
| } |
| inferConfig := map[string]any{ | ||
| "map_name_regex": "^" + regexp.QuoteMeta(param.MapName) + "$", | ||
| "precision": DEFAULT_INFERENCE_PARAM_FOR_MOVE.Precision, | ||
| "threshold": DEFAULT_INFERENCE_PARAM_FOR_MOVE.Threshold, | ||
| } | ||
|
|
||
| res, err := ctx.RunRecognition(nodeName, img, config) | ||
| inferConfigBytes, err := json.Marshal(inferConfig) | ||
| if err != nil { | ||
| log.Error().Err(err).Msg("Failed to run MapTrackerInfer") | ||
| log.Error().Err(err).Msg("Failed to marshal inference config") | ||
| return nil, err | ||
| } |
There was a problem hiding this comment.
doInfer 每次调用都构造 map 并 json.Marshal 推理配置;该函数在 100ms 循环内频繁调用,这会产生不必要的分配与 CPU 开销,抵消“快路径”收益。建议将 CustomRecognitionParam 预先构建(例如在 Run 开始时按 MapName 构造一次字符串),或改用 struct 并复用缓冲以减少热路径开销。
| var mapTrackerInferRunner maa.CustomRecognitionRunner = &MapTrackerInfer{} | ||
|
|
There was a problem hiding this comment.
这里引入了全局单例 mapTrackerInferRunner 用于内部快路径调用,但 register.go 仍注册了另一个独立的 &MapTrackerInfer{} 实例。这样会导致 maps/pointer/scale 缓存各自初始化两份、增加内存与加载开销,也可能让两条调用路径的缓存状态不一致。建议:注册时复用同一个 runner 实例(或在 doInfer 中复用已注册的实例)以确保缓存共享并减少重复初始化。
| var mapTrackerInferRunner maa.CustomRecognitionRunner = &MapTrackerInfer{} |
概要
此 PR 主要对 MapTrackerMove 节点引入了内部快路径推理,以解决 MaaXYZ/maa-framework-go#33 提出的 Native 延迟问题。
此外,引入了一个到达点位的角度判据,以更加鲁棒地判断到达点位。
此外,对某些参数和机制进行了精调。
Summary by Sourcery
通过引入内部快速路径推理管线,并优化移动与旋转行为,来加速 MapTrackerMove 导航、降低延迟,并提升到达检测的可靠性。
Bug Fixes(错误修复):
Enhancements(增强改进):
MapTrackerInfer运行器,而非通用识别管线,以降低开销和延迟。Original summary in English
Summary by Sourcery
Optimize MapTrackerMove navigation by introducing an internal fast-path inference pipeline and refining movement and rotation behavior for lower latency and more robust arrival detection.
Bug Fixes:
Enhancements: