I'm trying to constraint an object's vertical position to a certain height using soft constraints. This means it will behave like a spring. The constraints are solved using a sequential impulse solver. I'm using the technique shown in Eric Catto's Soft Constraints talk and Ming-Lun Chou's Soft Constraints video shown at the links below.
https://box2d.org/files/ErinCatto_SoftConstraints_GDC2011.pdf
https://www.youtube.com/watch?v=UUt4Lko2wFI
I'm having two problems. First, during the loop which solves the constraint iteratively, the result is different depending on the number of iterations.
5 iterations
20 iterations
As you can see, the box stops oscillating faster when there are more iterations. The number of iterations should not be affecting the box like this.
The second problem I'm having is that when I set zeta to 0 the box stops oscillating over time like in the above gifs. This should not happen as shown in Erin Catto's paper linked above:
As you can see, when zeta is 0, the box should oscillate forever and not come to rest. In both examples above, zeta is set to 0 and omega is set to 2 times pi.
Here is my implementation.
// Integrate
rigid_body.velocity.y += acceleration * delta_time;
transform.position.y += rigid_body.velocity.y * delta_time;
// Calculate constants
let d = 2.0 * rigid_body.mass * SPRING_ZETA * SPRING_OMEGA;
let k = rigid_body.mass * SPRING_OMEGA * SPRING_OMEGA;
let gamma = 1.0 / (d + delta_time * k);
let effective_mass = (1.0 / rigid_body.mass) + gamma / delta_time;
let beta = (delta_time * k) / (d + delta_time * k);
let pos_error = 3.0 - transform.position.y; // constrain the box to y = 3
let baumgarte = beta / delta_time * -pos_error;
// Solve the constraint
for _ in 0..iterations {
let velocity_error = rigid_body.velocity.y;
let lambda = -(velocity_error + baumgarte) / effective_mass;
rigid_body.velocity.y += lambda / rigid_body.mass;
}
// Integrate velocity
rigid_body.position.y += rigid_body.velocity.y * delta_time;
Here is a nice frame from Ming-Lun Chou's video linked above where you can reference the equations and compare them to my code.
I'm not able to find a mistake anywhere. Can anyone please help me understand why I'm experiencing these two issues and how I can fix them?