ERROR: Tried to remove agent with ID 66 from the space, but that agent is not on the space

I was wondering what is most efficient and issue free way to create random positions for agents.

At the moment Im using this where sides = [1e3, 1e2, 5e2]

positions = [sides .* rand(SVector{3,Float64}) for _ in 1:number_of_particles]

which works but sometimes throw this error when I try to run model


julia> adf, mdf   = run!(model, step_point; adata = [:vel, :pos], mdata = [:count], init = true, when = (model, t) -> true,  showprogress = false) 
ERROR: Tried to remove agent with ID 66 from the space, but that agent is not on the space
Stacktrace:
  [1] error(s::LazyString)
    @ Base ./error.jl:35
  [2] remove_agent_from_space!
    @ ~/.julia/packages/Agents/dTr7O/src/spaces/continuous.jl:143 [inlined]
  [3] move_agent!(agent::CELL, pos::SVector{…}, model::StandardABM{…})
    @ Agents ~/.julia/packages/Agents/dTr7O/src/spaces/continuous.jl:157
  [4] walk!
    @ ~/.julia/packages/Agents/dTr7O/src/spaces/walk.jl:64 [inlined]
  [5] move_agent!
    @ ~/.julia/packages/Agents/dTr7O/src/spaces/continuous.jl:187 [inlined]
  [6] agent_step!(agent::CELL, model::StandardABM{…})
    @ Main ~/PhD/Program_Julia/code/abm_vs_prob_test_eqidistance.jl:211
  [7] step_ahead!(model::StandardABM{…}, agent_step!::typeof(agent_step!), model_step!::typeof(model_step!), n::Int64, t::Base.RefValue{…})
    @ Agents ~/.julia/packages/Agents/dTr7O/src/simulations/step_standard.jl:17
  [8] step!
    @ ~/.julia/packages/Agents/dTr7O/src/simulations/step_standard.jl:5 [inlined]
  [9] _run!(model::StandardABM{…}, df_agent::DataFrame, df_model::DataFrame, n::Float64, when::Function, when_model::Function, mdata::Vector{…}, adata::Vector{…}, obtainer::typeof(identity), dt::Int64, p::ProgressUnknown)
    @ Agents ~/.julia/packages/Agents/dTr7O/src/simulations/collect.jl:166
 [10] run!(model::StandardABM{…}, n::Float64; when::Function, when_model::Function, mdata::Vector{…}, adata::Vector{…}, obtainer::Function, showprogress::Bool, init::Bool, dt::Float64)
    @ Agents ~/.julia/packages/Agents/dTr7O/src/simulations/collect.jl:148
 [11] top-level scope
    @ ~/PhD/Program_Julia/code/abm_vs_prob_test_eqidistance.jl:269
Some type information was truncated. Use `show(err)` to see complete types.

Although based on position output seems agent is in space.

julia> model[66].pos
3-element SVector{3, Float64} with indices SOneTo(3):
 599.9812375700334
  62.84457279233983
 486.74628139637053

@Sahil_Khan, I encountered the same problem. The agent is in the space, but an error is thrown. Did you figure out a solution?

I tried to simplify the example. It appears to happen several cycles after reflecting off a boundary.

Summary

`######################################################################################################

load dependencies

######################################################################################################
cd(@DIR)
using Pkg
Pkg.activate(“…/…/…”)
using Agents
using CairoMakie
using Random
######################################################################################################

define model

######################################################################################################
@agent struct PoorSoul(ContinuousAgent{2, Float64})
mass::Float64
end

function handle_collision(agent, model)
x, y = agent.pos
vx, vy = agent.vel
if x ≤ 0.0
println(“enter 1”)
x = 0.0
vx < 0.0 && (vx = -vx)
end
if x ≥ model.max_bound
println(“enter 2”)
x = model.max_bound
vx > 0.0 && (vx = -vx)
end
if y ≤ 0.0
println(“enter 3”)
y = 0.0
vy < 0.0 && (vy = -vy)
end
if y ≥ model.max_bound
println(“enter 4”)
y = model.max_bound
vy > 0.0 && (vy = -vy)
end
return SVector(x, y), SVector(vx, vy)
end

function initialize(;
speed = .002,
interaction_radius = 0.012,
dt = 1.0,
max_bound = 1,
n_agents,
)
properties = (;
interaction_radius,
dt,
max_bound,
)
space = ContinuousSpace((1, 1); spacing = 0.02, periodic = false)
model = StandardABM(
PoorSoul,
space;
agent_step!,
model_step!,
properties
)

# Add initial individuals
for _ ∈ 1:n_agents
    pos = Tuple(rand(Uniform(0, max_bound), 2))
    mass = 1
    vel = sincos(2π * rand(abmrng(model))) .* speed
    add_agent!(pos, model; vel, mass)
end
return model

end

function model_step!(model)
r = model.interaction_radius
for (a1, a2) in interacting_pairs(model, r, :nearest)
elastic_collision!(a1, a2, :mass)
end
end

function agent_step!(agent, model)
println(“agent id (agent.id)") new_position, new_velocity = handle_collision(agent, model) println("current position (agent.pos)”)
println(“new position $new_position”)
println(“”)
agent.vel = new_velocity
agent.pos = new_position
move_agent!(agent, model, model.dt)
end

Random.seed!(658)
model = initialize(; n_agents = 10, max_bound = .40)
run!(model, 40)

abmvideo(

“socialdist4.mp4”,

model;

title = “SIR model”,

frames = 300,

#agent_color = sir_colors,

agent_size = 10,

spf = 1,

framerate = 20

)

`

Here is the error several steps after reflexing off the boundary x = .40.

agent id 1
current position [0.39891378941222266, 0.22174779298576894]
new position [0.39891378941222266, 0.22174779298576894]

ERROR: Tried to remove agent with ID 1 from the space, but that agent is not on the space
Stacktrace:

Hello, :slight_smile:

Solution to problem is : move_agent!(agent, new_position, model)

Use above line in agent_step() before moving the agent.

Check out this code:


@agent struct PoorSoul(ContinuousAgent{2, Float64})
mass::Float64
end

function handle_collision(agent, model)
    x, y = agent.pos
    vx, vy = agent.vel
    if x ≤ 0.0
   
        x = 0.0
        vx < 0.0 && (vx = -vx)
    end
    if x ≥ model.max_bound
   
        x = model.max_bound
        vx > 0.0 && (vx = -vx)
    end
    if y ≤ 0.0
  
        y = 0.0
        vy < 0.0 && (vy = -vy)
    end
    if y ≥ model.max_bound
   
        y = model.max_bound
        vy > 0.0 && (vy = -vy)
    end
    return  @SVector([x, y]),  @SVector([vx, vy])
end

function initialize(;
    speed = .002,
    interaction_radius = 0.012,
    dt = 1.0,
    max_bound = 1,
    n_agents,
    )
    properties = (;
            interaction_radius,
            dt,
            max_bound,
    )
    space = ContinuousSpace((1, 1); spacing = 0.02, periodic = false)
    model = StandardABM(
            PoorSoul,
            space;
            agent_step!,
            model_step!,
            properties
    )

    # Add initial individuals
    for _ ∈ 1:n_agents
        pos = Tuple(rand(Uniform(0, max_bound), 2))
        mass = 1
        vel = sincos(2π * rand(abmrng(model))) .* speed
        add_agent!(pos, model; vel, mass)
    end
    return model
end

function model_step!(model)
    r = model.interaction_radius
    for (a1, a2) in interacting_pairs(model, r, :nearest)
        elastic_collision!(a1, a2, :mass)
    end
end

function agent_step!(agent, model)
    new_position, new_velocity = handle_collision(agent, model)
    agent.vel = new_velocity
    # this move_agent function changes agent to new position
    # Before you were giving new value to position but agent position was not 
    #actually getting updated. 
    move_agent!(agent, new_position, model)
    move_agent!(agent, model, model.dt)
end

Random.seed!(658)
model = initialize(; n_agents = 10, max_bound = .40)
run!(model, 40)

abmvideo(
    “socialdist4.mp4”,
    model;
    title = “SIR model”,
    frames = 300,
    #agent_color = sir_colors,
    agent_size = 10,
    spf = 1,
    framerate = 20
)
1 Like

Thank you for your help!

If I understand correctly, the critical change was the addition of move_agent!(agent, new_position, model) in agent_step!. I am assuming that it is needed to correctly set the position from the collision handler. Is that the case?

1 Like

Yes. Thats correct.

1 Like

Awesome. For future reference I will mark this as the solution, which is to add move_agent!(agent, new_position, model) when an agents position is changed. Credit goes to @Sahil_Khan for finding the solution.

Edit I cannot mark as the solution. Can you please mark it @Sahil_Khan ?

I have edited my answer to clearly state the main solution. :slight_smile:

1 Like