Discussion Modeling Boats, Ships, and Other Watercraft in Orbiter? Experiments with Hydrostatics and the Touchdown Model

Thunder Chicken

Resident Lua Script Rabble-Rouser
Donator
Joined
Mar 22, 2008
Messages
5,847
Reaction score
5,509
Points
188
Location
Massachusetts
So I have been trying to explore the boundaries of the physical modeling capabilities in Orbiter, not just for orbital dynamics and aerodynamics, but contact forces and buoyancy, in water as well as in the atmosphere.

After some explorations of the "new" touchdown model with my Zorb addon, I realized that it might be possible to model buoyancy for a vessel at the surface by relating the stiffness in the touchdown model to the hydrostatic equation which describes the pressure distribution on a semi-submerged vessel.

The Touchdown Model

The touchdown model applies a simple forced mass-spring-damper model to each of the contact points:[math]my'' + cy' + ky = \sum F_y[/math]
where m is the mass supported by the contact, y is the displacement, y' is the rate of displacement, and y'' is the acceleration. The coefficients are defined as:

Stiffness coefficient (Applied spring force per unit displacement): [math]k = F_S/y[/math]
Damping coefficient (Applied damping force per unit rate of displacement): [math]c = F_D/y'[/math]


So if you have a vessel with n contact points all at y = 0 (where y is in the local vertical direction opposite gravity), and you specify a vessel weight mg and a stiffness k, the mesh will "sink" until the weight is supported by the springs at a depth y = mg/nk, which looks something like this:

Spring_Model.png
Note that there are dampers in parallel with the springs to dissipate energy, but I've omitted them for clarity to focus on the spring forces. The dampers only oppose motion and don't apply forces in static situations.

The Hydrostatic Equation

The hydrostatic equation describes the increase in pressure in a fluid as depth increases. The pressure force at a given depth has to be equal to the weight of the fluid above it. If you visualize a vertical column of fluid with height y (again, in the direction of the local gravitational acceleration), and the column has a cross sectional area A, the increase in pressure [imath]\Delta P[/imath] at the bottom of the column relative to the top required to support the weight of the fluid is given by:

Pressure Force = Weight
[math]\Delta P A = \rho g y A[/math]
[math]\Delta P = \rho g y[/math]
The hydrostatic pressure for a given fluid is only a function of depth y. This pressure will apply a normal pressure force to any solid surface at that depth, regardless of the orientation of that surface.

Relating the Hydrostatic Pressure and Touchdown Stiffness

Touchdown forces only act in the local y direction, where hydrostatic forces can generally act in any direction depending on the orientation of a hull surface. However, if we use a simple rectangular solid as a vessel with the submerged surfaces parallel with the planet surface (similar to the schematic above), we can implement an accurate flotation model in Orbiter as it exists now. Assuming a simple 1 m cube with vertices on each corner, and we want it to float at the surface, so only the bottom four vertices are submerged. So the weight of the vessel is supported by n=4 springs, and that weight must be equal to the hydrostatic pressure force on the vessel:

Weight = Hydrostatic Force = Sum of Spring Forces​

For this to be true for the vessel to float at the surface, the density of the vessel cannot exceed the density of water ([imath]\rho[/imath] = 1000 kg/m3 for fresh water, somewhat higher for sea water).

So we can determine the necessary spring stiffness for the contact model by:

[math] mg = \rho g y A = n k y[/math]

[math] k = \rho g A / n[/math]

A / n describes the area associated with each vertex and the area upon which the local hydrostatic force acts.

Testing

So I coded a simple vessel with a 1 m cube as described above, and made a little add-on (attached). It has a magical massless thruster that allows it to leave the Landed state and be supported on the contact points, and to let users "poke" it to see it bob around. The mass was set to 500 kg, 50% the density of water. This cube should float halfway out of the surface when supported by its contact points if they mimic the hydrostatic forces correctly. In this case n = 4, and A = 1 m2.

At the start of the scenario the mesh is "Landed" at KSC (it's on the runway, any planet surface will work as we can't distinguish water from rock at the moment). It is hovering above the surface:

Screenshot at 2024-07-03 17-18-50.png
The mesh has a simple gradation texture measuring the 1 meter vertical dimension so we can visually see the depth to which it sinks. When we hit the throttle (thrust is in -Y direction and about 20% of the vessel mass), the vessel falls into the surface, bobs around a bit, and then stabilizes...at 0.5 m, as expected:
Screenshot at 2024-07-03 17-22-46.png

The selection of damping constant is more artistic. If the damping value is set to 0, this cube will bob up and down forever. If a small amount of damping is applied it will bob up and down a bit before coming to rest in a pleasantly realistic manner. A small fraction of the critical damping value for this system is used.

Initial Conclusions

So based on this, in Orbiter we currently can model reasonably accurate net buoyant forces on semi-submerged objects, so long as submerged surfaces are parallel to the planet surface.

In order to generalize this to more interesting hull shapes, two things would need to be accessible from Orbiter.
  1. The depth to each submerged vertex of the mesh with a corresponding touchdown point definition. This allows the magnitude of the hydrostatic force to be calculated. An area would also need to be associated to each vertex for this calculation.
  2. The mean normal vector from the surface at each vertex. The total hydrostatic force acts normal to the submerged surface, but only the y-component of that force vector helps support the weight of the vessel. Hydrostatic forces in the X- and Z- directions can be integrated, but they should be equal and opposite. It may be possible to use the mesh outward normals for this IF they are applied correctly.
If these are accessible and implemented correctly, this can model not just the net buoyant force, but the vessel stability.
 

Attachments

Last edited:
I let the simulation run for a while. Since there is no contact friction, the box started sliding down a shallow slope into one of the ditches surrounding the SLF and tilted as it fell in. It shows a self-righting capability. It bobs back and forth but remains upside up.

Screenshot at 2024-07-03 20-23-56.png
The mass of the vessel (0,0,0 in vessel coordinates) is at the bottom center of the box, so the contact model is correctly putting a center of pressure above that point. It likely isn't 100% accurate as the contact points are on the corners, not centered on the sub parcels of hull area.
 
Interesting behavior when I completely invert the box (zip file with .mp4 video attached). This isn't capturing the submersion of the upper surfaces of the cube properly, but it shows that the contact model can handle inversion.
 

Attachments

One challenge for accurate buoyancy modeling is locating the hydrostatic force vectors correctly. It's easy to determine the hydrostatic pressure at a given vertex depth, but to get the associated force vector (magnitude and location) requires integration of the pressure distribution and determination of the center of pressure location on the submerged surface. The center of pressure is always below the centroid of the submerged surface as pressure increases with depth.

This picture shows a simple 2D arrangement with the hydrostatic pressure distribution and the equivalent force vector that provides the same moment as the pressure distribution:

hydrostatic_force_submerged_surface.png

The magnitude of the force F is the "volume" of the pressure distribution, which is easy enough to calculate even in 3D. The trick is getting the depth / location of that force. There are analytical solutions for determining that location, but they require a coordinate system that is aligned with the flat surface and has an origin where a line parallel with that surface intersects the free surface, which is a nuisance for surfaces that can move in 3d.

There doesn't seem to be a convenient way to determine the equivalent location of the net hydrostatic force on a submerged surface. The spring contact model can calculate the hydrostatic pressure at each contact vertex, but we have no good way to apply an effective area to integrate those pressures into forces that can be used by the spring contact model. We could get a rough estimate by calculating the surface area and dividing that by the number of bounding vertices (as I did in the 1-D math in my original post), but unless you use a LOT of contact points OR are only working with flat surfaces parallel to the water surface that never change orientation, this will never be accurate.

It unfortunately may be necessary to ditch the contact point model and calculate the hydrostatic pressure at each bounding vertex on a submerged surface, then integrate the pressure distribution over that surface to get the magnitude and direction of the resulting force in the direction of the surface normal, then apply that force using add-force, all in that add-on code. For surfaces that are partially submerged, we'd have to figure out where the submerged surface intersects the free surface as the hydrostatic pressure is zero along that line.

On top of that, if we go that route, we lose access to the quick and easy damping in the contact model, so modeling bobbing on the surface would have to be rebuilt too.

TL;DR Getting something that looks about right can be done with the contact model as described above, but getting physically accurate and realistic results from that model may be very expensive or impossible. Need to do some more thinking on that.
 
So I attempted a couple methods to directly model buoyancy on surface vessel hulls, but they are computationally very challenging and cost a lot a framerate.

I figured out how to get the depth of exterior hull vertices in local coordinates using the vessel altitude and rotating from vessel coordinates to relative coordinates through pitch, roll, and yaw. That allows the pressure distribution on a surface to be determined, but things get ugly after that, particularly if the surface is semi-submerged. To integrate buoyant forces on the hull, you need to determine the net hydrostatic load and locate it at the center of pressure of only the submerged part of all the surfaces. This is possible but complicated to do in general. Even if this were done, this would produce a force vector on each surface where the magnitude AND location changes dynamically, and can change rather quickly, which quickly would punt you into space.

I also tried a point cloud method to integrate the volume and centroid of the submerged portions of the vessel in order to use Archimede's principle to determine the net buoyant force and its line of action. This works after a fashion, but even for a simple box it is very computationally expensive as you must perform this integration every time step, and in order to get accurate results you must count lots of points. Due to the granular nature of this model, you tend to get step changes in buoyant force as more points emerge/submerge, and again this causes fits with the propagators. Numerical underrelaxation helps somewhat with stability, but it causes the application of force to lag from the current state of the vessel, so too much underrelaxation leads to different instabilities. There really is no setting where the simulation is stable. The only way to "fix" this is to greatly increase the number of points in the point cloud, but that is murder on frame rate. I got a box that jumped in and out of the surface like a caffeinated dolphin which was amusing but far from correct. I have a video of it but I am refraining from posting it as I don't want to impose the storage on OF.

It seems that the contact model, while technically inaccurate, might be the least bad way to mimic buoyancy realistically in Orbiter in a stable fashion with minimum computational impact.
 
For fun I was going to see if I could put Benchy into Orbiter using the contact buoyancy model:

3DBenchy.png

I can get the stl file into Blender and export it as an Orbiter mesh, but I get this mess when I load it into Orbiter:

Screenshot at 2024-07-08 11-23-33.png
It is a single mesh group. Does anyone know what is occurring and if it is fixable? It's on its side and is too large but I can fix that. I can make a simple low poly boat mesh for testing, but I was hoping for something with a somewhat curvy hull. Benchy might be too many vertices to be efficient anyway.
 
Too many vertices in one mesh group, seperate into more groups and/or simplify the geometry.
 
I wonder if these touchdown points can be calculated dynamically to simulate a vehicle going over a bridge or an elevated landing pad/landing on an aircraft carrier or even a venus cloud colony if taken to the extreme.

I've tried my hand on adjusting the position of the touchdown points when at a certain radius from a pad but it doesn't seem to work. (or I am probably doing something wrong).
 
I wonder if these touchdown points can be calculated dynamically to simulate a vehicle going over a bridge or an elevated landing pad/landing on an aircraft carrier or even a venus cloud colony if taken to the extreme.

I've tried my hand on adjusting the position of the touchdown points when at a certain radius from a pad but it doesn't seem to work. (or I am probably doing something wrong).
This might be possible, but you need to remember that the contact model is a force model. By changing the touchdown point you are instantaneously changing the spring deflection hence the applied force. Also, if you have damping, that delivers another force that is proportional to how quickly the deflection changes. There is some risk of non-physical accelerations and yeetage to Alpha Centauri if this is not done carefully.
 
There is some risk of non-physical accelerations and yeetage to Alpha Centauri if this is not done carefully.
indeed, I experienced that. My guess is that dmping model and wheel/gear animation must be managed separately: you control the motion of the spacecraft from the dampling model, but you draw the contact points (gear...) without changing touchdown points value. At the end of the motion you modify the touchdown points at 1mm above what they shoud be and remove all dampling force.

wow, cool resource! BTW, is Frauenliebe GmbH the ad for the Austrian newspaper? :)
 
I wonder if these touchdown points can be calculated dynamically to simulate a vehicle going over a bridge or an elevated landing pad/landing on an aircraft carrier or even a venus cloud colony if taken to the extreme.

I've tried my hand on adjusting the position of the touchdown points when at a certain radius from a pad but it doesn't seem to work. (or I am probably doing something wrong).
I actually need to think about this a bit more. I think part of the problem is confusion about coordinate systems. Contact/touchdown points are defined relative to the vessel, but they ultimately ride on the planet surface, and your vessel hangs on it, just like the suspension of a car. It's still rather confusing to me as well. I think I will do some experiments with my box model and see if I can come up with any general insights.
indeed, I experienced that. My guess is that dmping model and wheel/gear animation must be managed separately: you control the motion of the spacecraft from the dampling model, but you draw the contact points (gear...) without changing touchdown points value. At the end of the motion you modify the touchdown points at 1mm above what they shoud be and remove all dampling force.
Yes, I think separating the force model and the mesh animations is necessary. This is something that I want to examine with my VW Thing model - how to get realistic wheel compliance motion.
 
I'm going to need a bigger smaller boat.
azG3Xnmu6o69JMh2pvJhdC-1200-80.jpg
Here you go, this should work in Orbiter (attached msh)
wow, cool resource! BTW, is Frauenliebe GmbH the ad for the Austrian newspaper? :)
No idea why the pics have that watermark. They are supposed to be directly by the author (Sergio Botero).
 

Attachments

I've started another thread on how to set touchdown points for vessels on a solid surface here:


I'll probably be expanding this with how to use the touchdown points to mimic vehicle suspension in wheeled vehicles in the near(ish) future, so stay tuned.
 
Benchy is floating:

Screenshot at 2024-11-17 19-36-36.png

Screenshot at 2024-11-17 19-43-51.png

The mesh file contains a single mesh group. I wrote a function to read the mesh file and sample every 100th vertex to make a coarse touchdown point cloud (still about 190 points, mostly on the hull). I assigned each point a "stiffness" of the specific weight of water multiplied by an effective area (roughly the total vessel surface area divided by the number of touchdown points). This doesn't exactly get the buoyancy right as you technically need to have the pressure in the direction of the vertex normals, but it floats and bobs about like a boat.

I set drag using set_cw with the coefficients about 1000 times higher than normal to account for the fact that the fluid it is in should be water. I gave it a thruster to put around with, and I tried to give it a rudder, but for some reason the rudder does not work.

I kinda would like a more realistic hull to play with as this is really a toy, but it's fun for starters.
 
Last edited:
Back
Top