NetLogo新增过程后报There is no agent for MYSELF to refer to错误
问题根因
报错核心是myself关键字的作用域误用,两处错误写法直接触发异常:
turn-amount是为patch设计的报告程序,内部依赖「运行代码的当前代理是patch、外层有调用它的turtle作为myself绑定对象」的上下文。原代码里turn-amount仅在min-one-of different-colored-neighbors [abs turn-amount]场景下运行:此时代码块对每个赛道patch执行,运行主体是patch,外层调用者是当前赛车turtle,myself能正确绑定到赛车,所以原代码可正常运行。但你在control-speed里直接无上下文调用turn-amount时,当前运行主体是赛车turtle,没有嵌套的外层代理上下文,turn-amount内部的myself找不到绑定对象直接抛错。- 超车判断里写的
[pcolor] of myself同样无有效上下文:这行代码不在ask/of/with的嵌套代理块里,myself没有绑定任何代理,也会触发报错。你这里的实际需求是判断侧前方patch是否和当前赛车脚下的赛道同色,根本不需要用myself。
另外你的代码里还有两处逻辑bug会导致运行异常:一是any?返回布尔值true/false,你写ifelse drafting = nobody属于类型不匹配的判断,逻辑完全失效;二是maxSpeed每次运行都在当前值上乘轮胎系数,会导致几帧内最高速度跌到接近0,赛车直接停在赛道上。
修复方案
- 删掉
cars-own里重复声明的speed变量,新增current-target-patch变量存储当前跟随的赛道patch,避免重复计算转弯量。 - 修改
face-chosen-neighbor过程,把选中的目标赛道patch存入赛车变量,供速度控制逻辑直接调用,不再无上下文调用patch专属的turn-amount过程。 - 重写
control-speed过程,修正myself误用、布尔值判断错误、速度衰减逻辑错误,新增速度下限防止赛车停驶。
修复后的完整相关代码如下:
; 修正变量定义 cars-own[ tyre-level tyre-type tyre-total speed maxSpeed draftSpeed current-target-patch ; 存储当前跟随的赛道目标patch ] to face-chosen-neighbor ;; turtle procedure set current-target-patch min-one-of different-colored-neighbors [abs turn-amount] rt [turn-amount * track-help] of current-target-patch end to control-speed ; 修正尾流判断逻辑:any?返回布尔值,直接判断即可 let drafting? any? other cars in-cone 4 130 let tyre-coef (tyre-level + 50) / tyre-total ifelse drafting? [ set maxSpeed draftSpeed * tyre-coef ][ ; 非尾流状态基于基础最高速30算系数,避免速度反复乘系数持续衰减 set maxSpeed 30 * tyre-coef ] ; 直接基于已存储的目标patch计算转弯量,不调用patch专属的turn-amount过程 let needed-turn subtract-headings (towards current-target-patch) heading if abs(needed-turn * track-help) > 60 [ set speed speed - (deceleration * abs(needed-turn) * 0.5) ] ; 修正前车获取逻辑:用one-of取到前车代理,不用any?存布尔值 let car-ahead one-of other cars in-cone 1 130 ifelse car-ahead = nobody [ ; 无前车时的加减速逻辑 ifelse speed < maxSpeed [ set speed speed + acceleration ][ set speed speed - deceleration ] ][ ; 有前车时的跟车/超车逻辑 ifelse [speed] of car-ahead >= maxSpeed [ set speed maxSpeed - deceleration ][ ; 直接取当前脚下patch的颜色作为赛道基准色,不需要用myself let track-color pcolor of patch-here let left-patch patch-left-and-ahead 90 1 let right-patch patch-right-and-ahead 90 1 ifelse [pcolor] of left-patch = track-color and not any? turtles-on left-patch [ move-to left-patch ][ ifelse [pcolor] of right-patch = track-color and not any? turtles-on right-patch [ move-to right-patch ][ ; 不具备超车条件时跟前车减速 set speed [speed] of car-ahead - deceleration ] ] ] ] ; 加最低速度限制,避免赛车停驶或倒车 if speed < 0.1 [set speed 0.1] end
关键规则备忘
self永远指代当前正在运行代码的代理;myself仅在ask/of/with形成的嵌套代理上下文里存在,指代外层触发这段嵌套代码的代理,顶层过程直接写myself一定会报错。any?返回布尔值,仅用于判断是否存在符合条件的代理;要获取符合条件的代理本身,用one-of取单个代理,或用agentset操作批量处理。
内容的提问来源于stack exchange,提问作者Koolade786
相关产品推荐
相关产品推荐

