Runge Kutta 4 For cloth simulation

Started by
12 comments, last by Shadx 18 years, 3 months ago
Hi all, This is a bit of a follow up of the following post : http://www.gamedev.net/community/forums/topic.asp?topic_id=367668 After seeing this post, I went back to my application and changed my Euler integrator for a RK4 integrator. I'm doing cloth simulation with point mass and when using the same Force and dampening for the spring as my Euler simulation, my RK4 becomes so unstable that I eventually lose my cloth. I also use the same time step for both my RK4 and Euler implementation. To make sure that my integrator was working properly, I compiled jjd's code(provided in the post referenced on top) and compared result in a free fall. Beside double vs float, the result of the free fall are similar. On a free fall, the simulation seems to fail on the introduction of small errors on x and z, caused by draging force acting on the particles. I would have thought that the integrator and calculating Hooke force with damping would easily take care of those errors. But they quickly get exagerated and the simulation gets out of control. Locking a point mass in position (or two for simulating a flag), makes the simulation much harder to debug, which is why I'm just currently dealing with free fall. I have to say that I can make it work, even with RK4, by bringing down the force of the spring and by bring up the dampening. Since RK4 should be more stable then Euler, I wouldn't expect that I had to do this though. My Euler simulation is the same except for the integration, how can it be more stable then RK4? On a free fall, the acceleration is constant. Using the integrator provided by jjd as an example, the result for the position in K2 and K3 is always the same, is this the expected result? All the example of derive function always seems to discard the time and use a constant acceleration. When I first started the implementation of RK4 on my cloth, I would recalculate the Hooke force between each node after a step (So calculate RK1 for all pointmass, then recalculate Hooke force, then calculate RK2...). I'm not sure that was the right approach, it just seemed like a very expensive operation to do. So when I changed this, I changed it so that I would perform the full RK4 calculation on each point mass. Before, my force would be different between each step (r1 to rk2 to rk3), so was my acceleration of course. But now, I calculate my Hooke force and then run the integrator, which means the acceleration is constant for every step and K2.pos == k3.pos, which seems pointless. Can anyone point me in the right direction for applying RK4 to cloth...anything beside going with verlet (that's my next project). Thanks, Shadx
Advertisement
Hi Shadx,

the short answer is that RK4 is more stable than Euler, so there is something going wrong in the code (either mine or yours). It's not clear to me exactly what is going on in your code. For instance, I'm not sure what the following sentence means

Quote:Before, my force would be different between each step (r1 to rk2 to rk3)


what are rk1, rk2, and rk3?

I'm going to have a look at my code and let you know if I find any problems. And there are a couple of points that you might want to consider: (1) cloth simulations often suffer from something called stiffness. This will screw up any explicit integrator like RK4 or Euler. However, I'm not sure if this is actually the problem you are having. (2) What timestep are you using? RK4 is not unconditionally stable. If the timestep is too large it will become unstable. If k is the string stiffness and m is the mass of a node in your mesh, then a rule of thumb is that your timestep should be less than sqrt(m/k).

--www.physicaluncertainty.com
--linkedin
--irc.freenode.net#gdnet

Quote:Original post by Shadx
Hi all,

This is a bit of a follow up of the following post : http://www.gamedev.net/community/forums/topic.asp?topic_id=367668

After seeing this post, I went back to my application and changed my Euler integrator for a RK4 integrator. I'm doing cloth simulation with point mass and when using the same Force and dampening for the spring as my Euler simulation, my RK4 becomes so unstable that I eventually lose my cloth. I also use the same time step for both my RK4 and Euler implementation.

To make sure that my integrator was working properly, I compiled jjd's code(provided in the post referenced on top) and compared result in a free fall. Beside double vs float, the result of the free fall are similar. On a free fall, the simulation seems to fail on the introduction of small errors on x and z, caused by draging force acting on the particles. I would have thought that the integrator and calculating Hooke force with damping would easily take care of those errors. But they quickly get exagerated and the simulation gets out of control.

Locking a point mass in position (or two for simulating a flag), makes the simulation much harder to debug, which is why I'm just currently dealing with free fall. I have to say that I can make it work, even with RK4, by bringing down the force of the spring and by bring up the dampening. Since RK4 should be more stable then Euler, I wouldn't expect that I had to do this though.

hardly so. in terms of gained stability, its certainly not worth the extra cycles you need to throw at it. i believe it allows for only about twice as big steps compared to euler, but its atleast 4 times as expensive to evaluate.

Quote:
On a free fall, the acceleration is constant. Using the integrator provided by jjd as an example, the result for the position in K2 and K3 is always the same, is this the expected result? All the example of derive function always seems to discard the time and use a constant acceleration. When I first started the implementation of RK4 on my cloth, I would recalculate the Hooke force between each node after a step (So calculate RK1 for all pointmass, then recalculate Hooke force, then calculate RK2...). I'm not sure that was the right approach, it just seemed like a very expensive operation to do.

So when I changed this, I changed it so that I would perform the full RK4 calculation on each point mass. Before, my force would be different between each step (r1 to rk2 to rk3), so was my acceleration of course. But now, I calculate my Hooke force and then run the integrator, which means the acceleration is constant for every step and K2.pos == k3.pos, which seems pointless.

the results should be the same for freefall for any > 1 order method, since freefall is itself a fenomena that is contant in its 2nd order derivative, and thus can be integrated exactly.

however, the hookean force is exactly which gives rise to a not-constant in any derivative at all situation. the point of higher order methods is to better approximate this non-constant force over the timestep with more samples, in order to reach higher accuracy. so if you dont resample your not-constant forces at every intermediate step, using a higher order method serves no point at all.

Quote:
Can anyone point me in the right direction for applying RK4 to cloth...anything beside going with verlet (that's my next project).

Thanks,

Shadx


i dont think there is much merit in simulating cloth with rk4 to begin with. its main advantage over euler is higher accuracy, but i suppose interactivity is more of a concern to you than physical perfection.
Hi jjd,

Sorry about not being more specific. rk1 = hf(x,yi) rk2 = hf(x+dt, yi + rk1/2) etc. At one point I had my simulation working in such a way that I would do:

CalculateForce();
//go through each point mass and get RK1
CalculateRK1();
//using the position and velocity in rk1, recalculate the force
CalculateForce();
CalculateRK2();
etc...

So my force was being recalculated between each steps. I'm not sure that was the right approach which is why I changed it to:
CalculateForce();
IntegrateRK4();

I do understand that I have to carefully chose my time step, my force and my damping factor. Which is why I was comparing with my Euler integrator. My feeling was that if my Euler integrator could take the parameter, so would the RK4. My mass is 0.5, my force K = 10000, damping is 0.5 and my timestep is 0.005. Your calculation would say that 0.007 would be acceptable. I'm suprised damping doesn't enter in that equation (sqrt(m/k)). I forgot to say that I also tried to constraint my springs if they get too far apart, the only thing this changes is how my piece of cloth makes it's exit off the screen (Do you prefer exploding fashion? Or simply a disapearing act?)

Thanks for the help.

Shadx
Quote:Original post by Eelco
i dont think there is much merit in simulating cloth with rk4 to begin with. its main advantage over euler is higher accuracy, but i suppose interactivity is more of a concern to you than physical perfection.


What I was aiming at was for higher stability so that I could increase my time step a bit. You are right, I'm not really looking for physical perfection, but I'm looking for swift reaction to force or collision with objects. Should I be looking at another method for spring surface or volume?

Shadx
Quote:Original post by Shadx
Hi jjd,

Sorry about not being more specific. rk1 = hf(x,yi) rk2 = hf(x+dt, yi + rk1/2) etc. At one point I had my simulation working in such a way that I would do:

CalculateForce();
//go through each point mass and get RK1
CalculateRK1();
//using the position and velocity in rk1, recalculate the force
CalculateForce();
CalculateRK2();
etc...


This is the correct way to do the calculation.

Quote:
So my force was being recalculated between each steps. I'm not sure that was the right approach which is why I changed it to:
CalculateForce();
IntegrateRK4();

I do understand that I have to carefully chose my time step, my force and my damping factor. Which is why I was comparing with my Euler integrator. My feeling was that if my Euler integrator could take the parameter, so would the RK4. My mass is 0.5, my force K = 10000, damping is 0.5 and my timestep is 0.005. Your calculation would say that 0.007 would be acceptable. I'm suprised damping doesn't enter in that equation (sqrt(m/k)). I forgot to say that I also tried to constraint my springs if they get too far apart, the only thing this changes is how my piece of cloth makes it's exit off the screen (Do you prefer exploding fashion? Or simply a disapearing act?)

Thanks for the help.

Shadx


Don't worry too much about the sqrt(m/k), that's just a rough guideline. Try reducing your stepsize to 0.0007. If that works fine, it might just be that your stepsize was too large.

--www.physicaluncertainty.com
--linkedin
--irc.freenode.net#gdnet

Quote:Original post by Shadx
Quote:Original post by Eelco
i dont think there is much merit in simulating cloth with rk4 to begin with. its main advantage over euler is higher accuracy, but i suppose interactivity is more of a concern to you than physical perfection.


What I was aiming at was for higher stability so that I could increase my time step a bit. You are right, I'm not really looking for physical perfection, but I'm looking for swift reaction to force or collision with objects. Should I be looking at another method for spring surface or volume?

Shadx


If you're more concerned about stability, there is a nice article or two on gamasutra about modelling constraints using Verlet. The other option that comes to mind is to use an implicit integrator. However, implicit integration is expensive and more complicated than what you've been doing so you'd better be sure you want/need to go down that path.

--www.physicaluncertainty.com
--linkedin
--irc.freenode.net#gdnet

Quote:Original post by jjd
If you're more concerned about stability, there is a nice article or two on gamasutra about modelling constraints using Verlet. The other option that comes to mind is to use an implicit integrator. However, implicit integration is expensive and more complicated than what you've been doing so you'd better be sure you want/need to go down that path.


Using implicit integration for cloth simulation can be extremely fast. Infact, just as fast as verlet integration.

The only hard/slow/scary thing that you have to do is to precompute the inverse of an extremely sparse NxN matrix.

A very detailed article can be found here.

When you use implicit integration, you can simulate large cloth, increase your time-step and mess up your cloth pretty badly before it "explodes".
Thanks everyone,

I'll start by going back and changing it to what it was originally (recalculating the force between each step). The RK4 calculation on my point mass isn't a complete waste at least and it was a good exercise. I'll look at other methods that a better suited for my goals.

Cheers!

Shadx



Quote:Original post by ury
Quote:Original post by jjd
If you're more concerned about stability, there is a nice article or two on gamasutra about modelling constraints using Verlet. The other option that comes to mind is to use an implicit integrator. However, implicit integration is expensive and more complicated than what you've been doing so you'd better be sure you want/need to go down that path.


Using implicit integration for cloth simulation can be extremely fast. Infact, just as fast as verlet integration.

The only hard/slow/scary thing that you have to do is to precompute the inverse of an extremely sparse NxN matrix.

A very detailed article can be found here.

When you use implicit integration, you can simulate large cloth, increase your time-step and mess up your cloth pretty badly before it "explodes".


True! I meant that it was more expensive per iteration, but you can recoup the cost by taking much larger steps.

--www.physicaluncertainty.com
--linkedin
--irc.freenode.net#gdnet

This topic is closed to new replies.

Advertisement