Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Instability at high speeds #3

Open
jonri opened this issue Oct 13, 2020 · 14 comments
Open

Instability at high speeds #3

jonri opened this issue Oct 13, 2020 · 14 comments
Assignees

Comments

@jonri
Copy link
Collaborator

jonri commented Oct 13, 2020

GNSS-Stylist/hydro@75149e7#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.

@fire
Copy link
Collaborator

fire commented Nov 21, 2020

How would we test this? Does it still fail?

@jonri
Copy link
Collaborator Author

jonri commented Nov 22, 2020

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.

@fire
Copy link
Collaborator

fire commented Nov 23, 2020

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

@jonri
Copy link
Collaborator Author

jonri commented Nov 29, 2020

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 jonri self-assigned this Nov 29, 2020
@GNSS-Stylist
Copy link

GNSS-Stylist commented Nov 29, 2020

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:

GNSS-Stylist@d9652fb
Minor fix (read edit-note below):
GNSS-Stylist@4297800

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 ( #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.

@jonri
Copy link
Collaborator Author

jonri commented Dec 3, 2020

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
Copy link
Collaborator Author

jonri commented Dec 4, 2020

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.

@fire
Copy link
Collaborator

fire commented Sep 4, 2022

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

@jonri
Copy link
Collaborator Author

jonri commented Sep 5, 2022

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.

@fire
Copy link
Collaborator

fire commented Oct 28, 2023

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

@MarieGrasmeier
Copy link

MarieGrasmeier commented Nov 30, 2023

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

@jonri
Copy link
Collaborator Author

jonri commented Dec 1, 2023

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...

@MarieGrasmeier
Copy link

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?

@jonri
Copy link
Collaborator Author

jonri commented Dec 1, 2023

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants