JuliaDynamics / Agents.jl

Agent-based modeling framework in Julia
https://juliadynamics.github.io/Agents.jl/stable/
MIT License
717 stars 115 forks source link

zombie example doesn't compile #911

Closed brianguenter closed 9 months ago

brianguenter commented 9 months ago

I downloaded the zombie example from the website (renamed it to Transport.jl but otherwise unchanged), created a new project that has just this file in it. Using Agents v 5.17.1.

Tried to execute the zombie example file and got this error:

Error message ``` julia julia> include("src/Transport.jl") ERROR: LoadError: MethodError: no method matching var"@agent"(::LineNumberNode, ::Module, ::Expr) Closest candidates are: var"@agent"(::LineNumberNode, ::Module, ::Any, ::Any, ::Any) @ Agents C:\Users\seatt\.julia\packages\Agents\xtlGn\src\core\agents.jl:210 var"@agent"(::LineNumberNode, ::Module, ::Any, ::Any, ::Any, ::Any) @ Agents C:\Users\seatt\.julia\packages\Agents\xtlGn\src\core\agents.jl:172 Stacktrace: [1] include(fname::String) @ Base.MainInclude .\client.jl:478 [2] top-level scope @ REPL[10]:1 in expression starting at C:\Users\seatt\Source\Transport\src\Transport.jl:21 ```
Code section where error occurs ``` julia module Transport # # Zombie Outbreak in a City # ```@raw html # # ``` # # This model showcases an ABM running on a map, using [`OpenStreetMapSpace`](@ref). # # ## Constructing the end of days using Agents using Random # We'll simulate a zombie outbreak in a city. To do so, we start with an agent which # satisfies the OSMSpace conditions of having a `pos`ition of type # `Tuple{Int,Int,Float64}`. For simplicity though we shall build this with the [`@agent`](@ref) # macro. @agent struct Zombie(OSMAgent) #ERROR OCCURS HERE infected::Bool speed::Float64 end # To be explicit, this macro builds the following type: # ```julia # mutable struct Zombie <: AbstractAgent # id::Int # pos::Tuple{Int,Int,Float64} # infected::Bool # speed::Float64 # end # ``` # where a tuple `(i, j, x)::Tuple{Int,Int,Float64}` means a position # on the road between nodes `i, j` of the map, having progressed `x` distance along the road. # The model constructor we build consists of a map, and 100 agents scattered randomly # around it. They have their own agenda and need to travel to some new destination. # Unfortunately one of the population has turned and will begin infecting anyone who # comes close. function initialise_zombies(; seed=1234) map_path = OSM.test_map() properties = Dict(:dt => 1 / 60) model = StandardABM( Zombie, OpenStreetMapSpace(map_path); (agent_step!)=zombie_step!, properties=properties, rng=Random.MersenneTwister(seed) ) for id in 1:100 start = random_position(model) # At an intersection speed = rand(abmrng(model)) * 5.0 + 2.0 # Random speed from 2-7kmph human = add_agent!(start, Zombie, model, false, speed) OSM.plan_random_route!(human, model; limit=50) # try 50 times to find a random route end ## We'll add patient zero at a specific (longitude, latitude) start = OSM.nearest_road((9.9351811, 51.5328328), model) finish = OSM.nearest_node((9.945125635913511, 51.530876112711745), model) speed = rand(abmrng(model)) * 5.0 + 2.0 # Random speed from 2-7kmph zombie = add_agent!(start, model, true, speed) plan_route!(zombie, finish, model) ## This function call creates & adds an agent, see `add_agent!` return model end # In our model, zombies are seemingly oblivious to their state, since they keep going about their # business, but start eating people along the way. Perhaps they can finally express their distaste # for city commuting. function zombie_step!(agent, model) ## Each agent will progress along their route ## Keep track of distance left to move this step, in case the agent reaches its ## destination early distance_left = move_along_route!(agent, model, agent.speed * model.dt) if is_stationary(agent, model) && rand(abmrng(model)) < 0.1 ## When stationary, give the agent a 10% chance of going somewhere else OSM.plan_random_route!(agent, model; limit=50) ## Start on new route, moving the remaining distance move_along_route!(agent, model, distance_left) end if agent.infected ## Agents will be infected if they get too close (within 10m) to a zombie. map(i -> model[i].infected = true, nearby_ids(agent, model, 0.01)) end return end # ## Visualising the fall of humanity # Notice that to visualize Open Street Maps, the package OSMMakie.jl must be loaded # as well, besides any Makie plotting backend such as CairoMakie.jl. using CairoMakie, OSMMakie zombie_color(agent) = agent.infected ? :green : :black zombie_size(agent) = agent.infected ? 10 : 8 zombies = initialise_zombies() abmvideo("outbreak.mp4", zombies; title="Zombie outbreak", framerate=15, frames=200, ac=zombie_color, as=zombie_size ) # ```@raw html # # ``` end # module Transport ```
Julia version ``` julia julia> versioninfo() Julia Version 1.9.3 Commit bed2cd540a (2023-08-24 14:43 UTC) Build Info: Official https://julialang.org/ release Platform Info: OS: Windows (x86_64-w64-mingw32) CPU: 16 × 11th Gen Intel(R) Core(TM) i7-11800H @ 2.30GHz WORD_SIZE: 64 LIBM: libopenlibm LLVM: libLLVM-14.0.6 (ORCJIT, tigerlake) Threads: 1 on 16 virtual cores Environment: JULIA_EDITOR = code.cmd ```
partial manifest file ```julia julia_version = "1.9.3" manifest_format = "2.0" project_hash = "cd1444dc7155b8d59eb2e22b371fe0fd6d28796b" [[deps.Agents]] deps = ["CSV", "CommonSolve", "DataFrames", "DataStructures", "Distributed", "Distributions", "Downloads", "Graphs", "JLD2", "LazyArtifacts", "LightOSM", "LinearAlgebra", "Pkg", "ProgressMeter", "Random", "Rotations", "Scratch", "StaticArrays", "StatsBase"] git-tree-sha1 = "adb98dc3c06912eb2af18ba80365b9a8a61806c5" uuid = "46ada45e-f475-11e8-01d0-f70cc89e6671" version = "5.17.1" [deps.Agents.extensions] AgentsArrow = "Arrow" AgentsOSMVisualizations = "OSMMakie" AgentsVisualizations = "Makie" [deps.Agents.weakdeps] Arrow = "69666777-d1a9-59fb-9406-91d4454c9d45" Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" OSMMakie = "76b6901f-8821-46bb-9129-841bc9cfe677" ```
Tortar commented 9 months ago

I think you probably opened the dev version (which deprecate the old way of declaring agents) of the docs since the definiton there matches yours while on the docs of 5.17.1 https://juliadynamics.github.io/Agents.jl/v5.17/examples/zombies/ the definition is

@agent Zombie OSMAgent begin
    infected::Bool
    speed::Float64
end

All the example seems to have syntax of the dev version actually. We will release 6.0 soon anyway so if you install the dev version you should be fine anyway :D

Tortar commented 9 months ago

Or even more probably the "edit on github" button sends to the repository at the latest commit

brianguenter commented 9 months ago

yep, that was the problem. Thanks.