Boat buoyancy and strange rotation-dependent rocking problem

Post Reply
fractalord
Posts: 3
Joined: Wed Nov 19, 2014 12:44 pm

Boat buoyancy and strange rotation-dependent rocking problem

Post by fractalord »

Hi to all!

First of all, sorry for my poor English. I'm doing a simple buoyancy model for a boat. I've read a few posts on this forum about this issue and they've helped me a lot. Everything's all right when the bow of my boat is pointing along the +x axis, but the more it's turned left or right the more my hull rocks like there was an imaginary wave from that side, and finally it turns back to it's starting rotation (along +x axis) and stops shaking. As far as I checked it doesn't depend on boat's starting rotation or position, waves height or direction (without any too).

My way of implementation buoyancy, drag and gravity is very similar to this: https://software.intel.com/sites/defaul ... rticle.pdf, but instead of applying central forces to the whole object i have many vertices inside my model and apply forces directly to each of them depends on their depth below water surface and local velocity.

I've tried creating my boat's rigid body with different starting rotation, but when it was rotated i.e. 90 degrees left, it was starting to shake immediately after program start and rotating to the only stable position, along the +x axis. I've tried rotating the model vertices in Blender on 90 degrees around y axis and export them to the .obj file again, from where I read them to my program, and then the stable rotation of my boat is along z axis, but it still gets rocked when rotated in other direction.

Do you have any ideas where the problem may came from and what can I do to fix this?
fractalord
Posts: 3
Joined: Wed Nov 19, 2014 12:44 pm

Re: Boat buoyancy and strange rotation-dependent rocking pro

Post by fractalord »

I recorded a short video to show you what the problem is.
https://www.youtube.com/watch?v=SI4RY_z842s
As you can see I'm trying to rotate the boat 3 times on different angles and each time it begins to shake and returns to it's default rotation (which is always along the x axis, no matter what's the hull's starting rotation). Here is some piece of code where i simulate the buoyancy force:

Code: Select all

void WaterManager::calculateBuoyancy(btDynamicsWorld *world, SimulationObject *object, btAlignedObjectArray<btVector3> &vertices) {
	btConvexHullShape *shape = (btConvexHullShape*)(object->getShape());
	
	btTransform transform = object->getRigidBody()->getCenterOfMassTransform();
	btVector3 vertex;
	btVector3 transformedVertex;
	
	btScalar waterDensity = 1000;
	btScalar depth;
	btScalar submerged;
	btScalar immersedVolume;               
	btScalar dragCoefficient = 0.42;
	btScalar vertexMaxHeight = 0.121;	// those values come from object's vertices grid
	btScalar vertexField = 0.125*0.232;	// 
	btScalar vertexMass = 1.0/(object->getRigidBody()->getInvMass())/(double)vertices.size();

	for(int i=0; i<vertices.size(); ++i) {
		vertex = vertices[i];
		transformedVertex = transform*vertex;
		depth = getHeight(transformedVertex.x(),transformedVertex.z())-(transformedVertex.y()); // getHeight(x,z) returns water surface level above/under (x,z) point on the horizontal plane
		submerged = 0.0;
		if(depth<vertexMaxHeight && depth>0.0)
			submerged = depth;
		if(depth>=vertexMaxHeight)
			submerged = vertexMaxHeight;
		immersedVolume = submerged*vertexField;
		btVector3 buoyancy(waterDensity*immersedVolume*-(world->getGravity()));
		btVector3 velocity = object->getRigidBody()->getVelocityInLocalPoint(vertex);
		btVector3 drag(0,0,0);
		if(depth>0.0)
			drag = btVector3(-0.5*waterDensity*velocity*velocity*vertexField*dragCoefficient); 
		btVector3 dragDirection = -velocity.normalized();
		object->getRigidBody()->applyForce(buoyancy,vertex);
		object->getRigidBody()->applyForce(dragDirection*drag.length(),vertex);
	}
}
Can somebody tell me why this direction along x axis is so special, that the boat always wants to turn in it?
I've noticed that when I apply central force then this bug doesn't appear, but the whole buoyancy looks unreal. Maybe it's something wrong with the transformation of vertices?

I really hope you can help me, because I've tried almost anything and don't know what to do to fix this.
Basroil
Posts: 463
Joined: Fri Nov 30, 2012 4:50 am

Re: Boat buoyancy and strange rotation-dependent rocking pro

Post by Basroil »

It looks like it's under the influence of a 6dof constraint with zeros oriented on the x axis. Sure that the only thing affecting that body is buoyancy? Perhaps your rotation method isn't as clean as it should be?
fractalord
Posts: 3
Joined: Wed Nov 19, 2014 12:44 pm

Re: Boat buoyancy and strange rotation-dependent rocking pro

Post by fractalord »

Basroil wrote:It looks like it's under the influence of a 6dof constraint with zeros oriented on the x axis. Sure that the only thing affecting that body is buoyancy? Perhaps your rotation method isn't as clean as it should be?
I really appreciate your help Basroil, thanks a lot!
I don't know which 6dof constraint you are talking about, I think I don't have it in my program or I don't know enough about Bullet's implementation. Where I can find the one you've mentioned?
I thought that was caused by buoyancy, because if I turned it off everything seemed to work more or less properly, but now I looked at it closer and it occured that the changes appeared too quickly and I wasn't able to catch them. I reduced boat's mass to something relatively small and changed it's initial rotation, then I've noticed that even without buoyancy the boat starts to turn in the way that it shouldn't, so it's not the buoyancy's fault.
The only forces affecting my boat are gravity, buoyancy and drag, I think. I'm pretty sure I didn't implemented anything else on my own.

This is the way I'm rotating the hull:

Code: Select all

	btTransform transform = boatSimulationObject->getRigidBody()->getCenterOfMassTransform();
	btQuaternion rotation = transform.getRotation();
	btQuaternion rotationChange;
	rotationChange = rotationChange.getIdentity();
	if(keys['r'])
		rotationChange.setY(0.005);
	else if(keys['t'])
		rotationChange.setY(-0.005);
	rotation = rotationChange*rotation;
	transform.setRotation(rotation);
	boatSimulationObject->getRigidBody()->setCenterOfMassTransform(transform);
Is it properly?

It works the same when I change boat's initial position away from (0,0,0).
If it can help: when I turn off buoyancy and leave only the drag and gravity the boat rotates a bit. When I turn off drag and leave buoyancy and gravity it rotates very much.
Basroil
Posts: 463
Joined: Fri Nov 30, 2012 4:50 am

Re: Boat buoyancy and strange rotation-dependent rocking pro

Post by Basroil »

After looking at it a few times the only thing I can imagine is that your equations are somehow constraining the boat like a 6dof constraint would do. Here's a few things that may help in determining where the issue is:
1) Use a simpler model, like a cube or pyramid
2) Test with high/normal/no drag and high/normal/no bouyancy
3) Run in debug and print out the forces at each vertex when rotating


The vertex method may be flawed, as the surface area and average normals are likely not equal between different vertex (and the rest of the math might be affected by it). Perhaps testing the method with face centers and normals (with both buoyancy and drag multiplied by the face area) could yield better results (at the cost of a bit more precomputation, but once you calculate those numbers it would be more or less the same)
Post Reply