hydro icon indicating copy to clipboard operation
hydro copied to clipboard

Instability at high speeds

Open jonri opened this issue 3 years ago • 14 comments

https://github.com/GNSS-Stylist/hydro/commit/75149e76ffff8c7464a9200f2029def451c1065e#diff-e96cb3bbcb7e2b7c1df0da90454e846ddeb6bffd170d49ca9f97fad1b2cae49fR181 contains a hack to limit velocity to 10 m/s, reportedly there is instability above this number.

Investigate whether this is a bug or a limitation of the engine. If there is no workaround, this should be documented.

jonri avatar Oct 13 '20 22:10 jonri

How would we test this? Does it still fail?

fire avatar Nov 21 '20 17:11 fire

I was going to start by creating a test scene that accelerates a boat up to a given speed and crashes it into an object or multiple objects. We probably need to try colliding against trimesh collision shapes as well as primitives or convex hulls.

If we come up with a scene that reproduces the problem, the next step would be to recreate an equivalent collision on land (for example sliding the same shapes across a flat surface instead of water) and see if those collisions work as expected.

If both scenarios break, then we chalk this up to a limitation of the physics engine itself. If only the hydro scenario fails, then we can start debugging to see which forces are at fault.

jonri avatar Nov 22 '20 17:11 jonri

10 m/s is very suspicious though. Isn't that the gravity constant?

fire avatar Nov 23 '20 21:11 fire

9.8 m/s^2 is the gravity constant, it's acceleration and not velocity. I think 10 m/s was just a nice round number so it's a coincidence.

I've reached out to the person who discovered the issue to see if they have any insights into what conditions would replicate this issue. I've tried a handful of things myself, and I can cause the issue two ways:

  1. Using the Godot physics engine instead of Bullet. Super-massive boats simply disappear, for smaller boats collision is glitchy. I'm not going to worry about this case, but I should document it.
  2. Turning the physics FPS down to 10 or below. In this case, it's possible that a large delta is amplifying a small inaccuracy that otherwise tends to balance itself out on average. We might be running into floating point precision errors - at 10 FPS the problem was again only happening with very massive boats.

jonri avatar Nov 29 '20 00:11 jonri

The aforementioned hack prevented objects with a flat underside from bouncing from the water surface when hitting it. Comment about "multiple colliding bodies" may not actually be relevant.

Forked the repo and modified the demo to show this "bouncing" behavior:

https://github.com/GNSS-Stylist/hydro-1/commit/d9652fb2a6736941cd620dd9467478f924bdb923 Minor fix (read edit-note below): https://github.com/GNSS-Stylist/hydro-1/commit/42978009532dbf95e94e60b3094339eb437ef4b1

With a 20 x 5 x 1 (1 being height) plate (mass 20000) dropped from the height of 30 and viscosity of 1 the plate bounces from a flat water surface few times before turning a little (likely due to rounding errors) and then settling to the surface of the water. If viscosity is higher bouncing keeps increasing.

If the physics FPS is grown from the default 60, viscosity can also be increased before bouncing happens. I remember pondering if the total impulse to the object could be somehow limited to a value that just stops the object in one physics frame instead of sending it back to the direction it came from. But couldn't find a working solution so used that hack instead (which basically just moves the problem farther instead of fixing it).

Edit: Forgot that I had get_area-function fixed in my own project ( https://github.com/godot-extended-libraries/hydro/issues/4 ). This, combined with a fix in the new hydro module halved the area causing drag. This led the drag force to also halve in my tests. Therefore the plate dropped from 15 m and viscosity being 2.8 (as previously described) using correctly fixed get_area led it to fly to the sky instead of bouncing few times as described before. Fixed the text above to reflect this.

GNSS-Stylist avatar Nov 29 '20 22:11 GNSS-Stylist

Hi @GNSS-Stylist thanks for taking the time to come up with a reproduction of the issue! I built my own test using your same specifications and can indeed reproduce the issue myself. Now time to dig in and find out what is happening...

jonri avatar Dec 03 '20 03:12 jonri

I believe the issue is that when an object is dropped into the water from some height, the actual force of collision becomes significant. The instant the bottom of the object hits the water at speed, the only force calculated at the moment is the drag force of the water. At an impact speed greater than the terminal velocity the object would have inside the water, the drag exceeds the incoming force, resulting in the object flying back upwards.

In reality, an object colliding with the water in this fashion should also be treated as an inelastic collision, as some of the impact force will be transferred to the water the object starts to displace. The real-world result is a splash and ripples or waves moving away from the object as its kinetic energy is redirected.

To solve this problem, we need to figure out when a face just starts to collide with the water and reduce the amount of force considered in the drag equation by some factor. This will simulate the force getting redirected as described above. The amount of reduction needs to be significant when the collision happens at a high speed, and more negligible when the object is at rest.

If this approach is successful, we could also export the amount and locations of the redirected force through a signal. This could help users to draw splash particles and play sounds proportional to the force of impact with the water.

jonri avatar Dec 04 '20 04:12 jonri

Can you check if this is in 4? I also try to check with a large height fall.

fire avatar Sep 04 '22 18:09 fire

It's on my list to revisit for sure. I want to see if enabling 64-bit precision fixes or reduces the issue, which should be possible to try in 4 now. We are adding up a lot of small per-face forces so there is potential to accumulate rounding errors.

jonri avatar Sep 05 '22 13:09 jonri

I found where I put the old version of the test https://github.com/fire/WaterwaysDemo/tree/hydro. "duckies in a flow field".

fire avatar Oct 28 '23 15:10 fire

10 m/s is very suspicious though. Isn't that the gravity constant?

Did anyone try it with bodies of different lengthes? I used a boat hull of 6.5 meters and the simulation freaked out at approx 3.5 m/s, which is close to the boat's hull speed of 3.18 meters. Hull speed mainly depends on the hull's length, meaning longer ships can reach higher speeds in displacement mode. As far as I understand the source code (not a C++ programmer), the model is only valid in displacement mode and cannot simulate planing of hulls. Edit: observed it in Godot 4.2

MarieGrasmeier avatar Nov 30 '23 21:11 MarieGrasmeier

As far as I understand the source code (not a C++ programmer), the model is only valid in displacement mode and cannot simulate planing of hulls.

I approximate the drag and lift forces caused by movement through the water here: https://github.com/godot-extended-libraries/hydro/blob/master/src/hydro_rigid_body.cpp#L196

Compared to the buoyancy forces from simple displacement, the math to do this correctly is much more complicated and I haven't yet figured out which other pieces are most important to make the simulation more realistic. Nevertheless, these forces should be enough to make a boat-shaped hull lift out of the water when it's moving.

Your hull speed observation is interesting though, another rabbit hole for me to go down...

jonri avatar Dec 01 '23 03:12 jonri

As far as I understand the source code (not a C++ programmer), the model is only valid in displacement mode and cannot simulate planing of hulls.

I approximate the drag and lift forces caused by movement through the water here: https://github.com/godot-extended-libraries/hydro/blob/master/src/hydro_rigid_body.cpp#L196

Compared to the buoyancy forces from simple displacement, the math to do this correctly is much more complicated and I haven't yet figured out which other pieces are most important to make the simulation more realistic. Nevertheless, these forces should be enough to make a boat-shaped hull lift out of the water when it's moving.

Your hull speed observation is interesting though, another rabbit hole for me to go down...

Thank you for clarification. That is plausible since I used a displacement hull that cannot plan. In real life, it would just produce a vast amount of wave instead of gaining speed. I will try and run some tests with a planing hull design and see what happens. How is the hull shape considered in the simulation?

MarieGrasmeier avatar Dec 01 '23 06:12 MarieGrasmeier

How is the hull shape considered in the simulation?

The simulation loops through each face in the hull. Based on the face's area and its angle relative to the velocity, it will cause a drag or lift force to be applied. We accumulate the small forces contributed by each face to generate the overall effect on the hull.

For simplicity, consider a flat plane at a 45° angle moving through the water. Half of the water resistance would oppose your motion and half would be redirected downwards, pushing the plane up out of the water.

In real life, it would just produce a vast amount of wave instead of gaining speed.

I think this is another manifestation of the same case I mentioned earlier in this thread relating to objects falling into the water. At higher velocities, the force that gets transferred into pushing the water (generating a splash when falling in, or a bow wave in your case) becomes significant and is important for reducing the velocity of the object. This should be related to the forces described above, but they are not adequate to account for this correctly. I need to revisit this again, maybe from the perspective of the conservation of momentum.

jonri avatar Dec 01 '23 12:12 jonri