JuliaDynamics/Agents.jl

zombie example doesn't compile

Closed this issue · 3 comments

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> 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
module Transport

# # Zombie Outbreak in a City
# ```@raw html
# <video width="auto" controls autoplay loop>
# <source src="../outbreak.mp4" type="video/mp4">
# </video>
# ```
#
# 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
# <video width="auto" controls autoplay loop>
# <source src="../outbreak.mp4" type="video/mp4">
# </video>
# ```


end # module Transport
Julia version
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_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"

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

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

yep, that was the problem. Thanks.