1
\$\begingroup\$

Let's say I have a 1-dimensional spring, and I want to simulate it by applying a force that may vary with time. We can skip friction and dampeners for now.

From what I learned many years ago in high school physics, one can apply Hooke's law and calculate the resulting force, which can be applied to calculate the resulting displacement.

Here's a trivial snippet that in principle does just that:

float spring = stiffness * displacement;
float totalForce = force - spring;
displacement += (velocity * deltaTime) + (totalForce * deltaTime * deltaTime / 2.0f);
velocity += totalForce * deltaTime;

I'm over simplifying some things, like the mass of the spring, and this is by design. I'd rather have a simple system than a complex one that is perfectly physically accurate.

With a non-zero initial displacement, and zero force, this should oscillate in place. However, when I actually go and simulate it, the oscillation magnitude grows and grows infinitely.

I tried plotting this, and this is the result:

Oscillation exploding

I'm reading some stuff online, and it seems like this method is infamous for being unstable, although it's not really clear to me why.

I'll continue researching, but is there a way to fix my method so it's more stable, or alternatively, is there a known simple, stable method to simulate something that looks like a spring? Once again, simplicity is more important than perfect accuracy.

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Your problem: using a Discrete Feedback Model

What this means is that your future spring's state depends on its current state. The force actively changes depending on what position it is right now.

Now, normally that's not a problem. In theory. Regular springs in the real world can be demonstrated to have this property. However, your issues is that you're simulating it discretely - meaning you're using time steps.

A normal spring is continuous, which means the laws of physics apply at every moment in time. Your spring, however, has its physics calculated every time step. This means that you miss all of the physics that happens between the time steps, and that introduces bias into your forces. Bias, in turn, will amplify instability in an unstable model, which is just what your spring happens to be.

Just to demonstrate this, try changing your time step. It should change the pattern of instability of your plot, though it will still be inherently unstable.

An easy fix would be to introduce a dampening term. With a sufficiently small time step, this means that the spring would stabilize, though it would eventually stop over time. You want a spring that keeps going forever, though, so let's talk how to get that.

Your solution: using a Mathematical Model

For a spring without dampening, the position-vs-time graph you want matches the equation for harmonic motion:

x(t)=Acos(ωt+ϕ)

Now you can calculate the A, ω, and ϕ terms using your spring equation and information you already know. For your case, it's pretty easy:

A = starting displacement

ϕ = 0 (because you're starting at maximal displacement)

ω can then be calculated with your spring equation: enter image description here

Whenever you want to know the position, you can just query this equation using the time since the spring started springing. You can of course add more terms onto this, depending on what you want.

Of course, there are also issues with how this will interact with other things in your simulation. If you want a spring, that, say, reacts when you hit it with something, then you'll just have to recalculate the equation at the point that you hit it. This is very doable, but it can make the math a little more complex.

This text is really useful to figure out how to do further calculations.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .