NetLogo中如何划分智能体视野并检测左右视野内的其他智能体
解决NetLogo智能体视野区域的左右侧区分问题
需求回顾
需要将智能体感知范围划分为4个区域:
- 以朝向为中心的前方视野锥
- 与前方锥区分开、角度相等的左侧/右侧视野锥
- 后方盲区
当前已实现前方和合并的侧方区域检测,但无法区分左右侧,需要实时获取各区域内的智能体数量。
解决方案
方法1:预先划分左右侧视野Patch集合
直接拆分侧方区域为左、右独立的视野锥,后续可直接基于Patch集合统计智能体。
1. 调整全局变量
将合并的vision-peripheral拆分为左右侧独立变量:
globals [ vision-front ; 前方视野Patch集合 vision-left ; 左侧视野Patch集合 vision-right ; 右侧视野Patch集合 ]
2. 重构视野划分逻辑
计算单侧侧方视野的角度宽度,分别生成左、右视野锥:
to get-vision let perception-distance perception-distance ; 感知距离 let front-angle front-angle ; 前方视野总角度(α) let full-angle full-angle ; 前方+两侧总视野角度(β) let side-angle (full-angle - front-angle) / 2; 单侧侧方视野角度 ; 前方视野:当前朝向为中心,角度front-angle set vision-front patches in-cone perception-distance front-angle ; 左侧视野:中心朝向 = 当前朝向 - (前方半角 + 侧方半角),角度side-angle set vision-left patches in-cone perception-distance side-angle (heading - (front-angle / 2 + side-angle / 2)) ; 右侧视野:中心朝向 = 当前朝向 + (前方半角 + 侧方半角),角度side-angle set vision-right patches in-cone perception-distance side-angle (heading + (front-angle / 2 + side-angle / 2)) ; 调试用颜色标记(可选) ask vision-front [set pcolor green] ask vision-left [set pcolor yellow] ask vision-right [set pcolor cyan] end
3. 检测并统计各区域智能体
基于划分好的Patch集合,直接统计或判断智能体位置:
to detect ; 实时统计各区域其他智能体数量 let front-count count other turtles-on vision-front let left-count count other turtles-on vision-left let right-count count other turtles-on vision-right ; 输出结果(替换为业务逻辑即可) print (word "前方智能体数: " front-count) print (word "左侧智能体数: " left-count) print (word "右侧智能体数: " right-count) ; 单个智能体区域判断示例 ask other turtles [ cond [member? patch-here vision-front] [print (word "智能体" who "在前方")] [member? patch-here vision-left] [print (word "智能体" who "在左侧")] [member? patch-here vision-right] [print (word "智能体" who "在右侧")] [true] [print (word "智能体" who "在盲区")] ] end
方法2:通过相对方向判断智能体区域
无需预先划分Patch集合,直接计算其他智能体相对于当前智能体的方向差,判断所属区域,适合仅关注智能体位置的场景。
to detect-by-direction let front-half front-angle / 2 ; 前方视野半角 let full-half full-angle / 2 ; 总视野半角 ; 统计各区域智能体数量 let front-count count other turtles with [ let rel-dir (towards myself - myself::heading) mod 360 if rel-dir > 180 [ set rel-dir rel-dir - 360 ] abs(rel-dir) <= front-half ] let left-count count other turtles with [ let rel-dir (towards myself - myself::heading) mod 360 if rel-dir > 180 [ set rel-dir rel-dir - 360 ] rel-dir < -front-half and rel-dir >= -full-half ] let right-count count other turtles with [ let rel-dir (towards myself - myself::heading) mod 360 if rel-dir > 180 [ set rel-dir rel-dir - 360 ] rel-dir > front-half and rel-dir <= full-half ] print (word "前方: " front-count " | 左侧: " left-count " | 右侧: " right-count) ; 单个智能体区域判断 ask other turtles [ let rel-dir (towards myself - myself::heading) mod 360 if rel-dir > 180 [ set rel-dir rel-dir - 360 ] cond [abs(rel-dir) <= front-half] [print (word "智能体" who "在前方")] [rel-dir > front-half and rel-dir <= full-half] [print (word "智能体" who "在右侧")] [rel-dir < -front-half and rel-dir >= -full-half] [print (word "智能体" who "在左侧")] [true] [print (word "智能体" who "在盲区")] ] end
方法对比
- 方法1:预先划分Patch集合,适合需要频繁操作区域内Patch的场景,但会占用更多内存。
- 方法2:动态计算相对方向,内存占用低,适合仅关注智能体位置的场景。
内容的提问来源于stack exchange,提问作者tinkyqal
相关产品推荐
相关产品推荐

