I'm trying to set up a basic continuous callback on a Julia ODE solver. I'm trying to model a ball bouncing and I've been following the example given in the documentation about events and callback functions for the Julia package DifferentialEquations.jl here.
The code I have so far is not particularly long or complicated so I'll paste it here in its entirety:
using DifferentialEquations
using GLMakie
using CommonSolve: init, step!
const fps = 45
const g = 9.81
f(v, y, p, t) = -g
prob = SecondOrderODEProblem(f,0,1,0.01)
condition(u, t, integ) = u[2]
function affect!(integ)
integ.u[1] = -integ.u[1]
end
cb = ContinuousCallback(condition, affect!)
integ = init(prob, Tsit5(), callback = cb)
ball = Observable(Point2f(0.5,1))
floor = [Point2f(0,0), Point2f(1,0)]
fig = Figure(); display(fig)
ax = Axis(fig[1,1])
lines!(ax, floor; linewidth = 4, color = :purple)
# markersize is the radius pixels of the marker, therefore the boundary of the disc is 12 pixels
# from the position of the disc if markersize = 12
scatter!(ax, ball; marker = :circle,
color = :black, markersize = 12
)
#ball[] = Point2f(0.5, 1)
for i in 1:100
@show (integ.u[1], integ.u[2]), integ.t
step!(integ)
ball[] = Point2f(0.5, integ.u[2])
#autolimits!(ax)
sleep(1/fps)
end
The code should execute as follows. A ball is plotted at (0.5, 1) and a line with endpoints (0,0) and (1,0). I've set up a second order ode problem so that the ball accelerates downwards at a rate of g. When the ball reaches the floor the affect! function should be called to reverse the velocity of the ball so that it bounces.
But when I run this code I get the error:
MethodError: no method matching setindex!(::Float64, ::Float64, ::Int64)
when the function affect! is called. As far as I can tell I've followed the example given in the DifferentialEquations.jl documentation properly so I don't understand why this error is happening. Can anyone point me to what I'm doing wrong?
The documentation mentions something about saving values between discontinuous changes to the state of the integrator so I attempted that but it did nothing.
I tried to simply print the value of integ.u[1] in affect! to see if there was an issue with getting the value, but it worked fine, so it seems to be an issue with actually assigning a new value to integ.u[1].
Appreciate the help!