4 ms·
Closed-form (non-iterative) PID solution: https://www.desmos.com/calculator/mu80ttc9aa https://www.desmos.com/calculator/mu80ttc9aa function sprung_respons
by EsportToys 1y ago
Closed-form (non-iterative) PID solution:
https://www.desmos.com/calculator/mu80ttc9aa https://www.desmos.com/calculator/mu80ttc9aa
function sprung_response(t,pos,vel,k,c,m)
local decay = c/2/m
local omega = math.sqrt(k/m)
local resid = decay*decay-omega*omega
local scale = math.sqrt(math.abs(resid))
local T1,T0 = t , 1
if resid<0 then
T1,T0 = math.sin( scale*t)/scale , math.cos( scale*t)
elseif resid>0 then
T1,T0 = math.sinh(scale*t)/scale , math.cosh(scale*t)
end
local dissipation = math.exp(-decay*t)
local evolved_pos = dissipation*( pos*(T0+T1*decay) + vel*( T1 ) )
local evolved_vel = dissipation*( pos*(-T1*omega^2) + vel*(T0-T1*decay) )
return evolved_pos , evolved_vel
end
For anticipation, just add an extra initial velocity in the opposite direction and let the closed-form solution handle the time evolution. The main trick here is to keep both position and velocity as state. There is no need to “step through the simulation”.
- thomascountz 1y agoWow, this is great!
- joenot443 1y agoWow, this is excellent! Is there a name for this kind of motion? I'd love to use it sometime.
- EsportToys 1y agoIt’s the general solution to a damped harmonic oscillator/mass-spring-damper system: m * x’’ + c * x’ + k * x = f(t) See https://web.archive.org/web/20230604215211/https://esporttoys.pages.dev/2022/11/21/damped https://web.archive.org/web/20230604215211/https://esporttoy...
- pahgawk 1y agoThis is good! Although I'd also say that initial velocity doesn't quite cover what I was talking about in the post -- even anticipation arguably can start from 0 velocity, accelerate backwards, decelerate, then accelerate in the opposite direction. Imo, any sudden change in velocity should by default be avoided (there are always valid uses where breaking that expectation is good, but I'd want it smooth by default.) That could possibly be done by incrementally changing force to move it back first, then forward, or to model this as a PD controller following an input with some baked in reversal before moving forward. That can still be closed-form (state response to a known input will be; Laplace transforms can help there), but still would need a bit of effort to model and tune to look right.
- LegionMammal978 1y agoYou wouldn't really need an incremental force: a step-function force (first backward for some time steps, then instantly forward) will still produce a continuous velocity curve.
- pahgawk 1y agotrue! I suppose you'd risk getting some oscillations in the anticipation depending on the scale of the force, but that could be desirable, or might not happen if the scale is small enough, and certainly makes the math a little easier
- EsportToys 1y agoYou can trivially calculate the time-to-peak overshoot using the closed form equation. It’s the first (0-indexed) zero of the velocity response, i.e. happens at t = (pi / scale) And obviously it would only apply for the underdamped case.
- creata 1y agoMaterial Design 3's "motion physics system" uses damped harmonic oscillators, too. The parameters (undamped angular frequency omega0 and damping ratio zeta) they use are on this page: https://m3.material.io/styles/motion/overview/how-it-works https://m3.material.io/styles/motion/overview/how-it-works
- ww520 1y agoWow. This is so good. I would never imagine using PID control for animation motion. Saving this.
- deleted 1y ago[deleted]
- esafak 1y agoHow did you even find this site; did you make it?