Propagating collisions in a mixed chain Dynamic/Kinematic

Post Reply
Dox
Posts: 24
Joined: Thu Oct 18, 2018 5:16 pm

Propagating collisions in a mixed chain Dynamic/Kinematic

Post by Dox » Wed Mar 27, 2019 3:09 pm

Hello,

I'm working on a mixed chain of dynamic and kinematic objects, as shown in this picture:
chain.png
Mixed chain
chain.png (5.68 KiB) Viewed 912 times
There is one dynamic object (red) moved by forces which is connected to a kinematic object (moved by geometrical rules) composed of 3 collision shapes (blue cloud). So, the kinematic group is modeled by 3 collision shapes owned by 3 btRigidBody (created as kinematics).

I can correctly move the kinematic group by my rules and the red dynamic object by forces. If I move the dynamic red object under forces, the "kinematic group" move itself via the motion state staying together. Obviously, the kinematic group can interact with others dynamics objects.

Goal: I need to propagate the collisions taken by the kinematic group to the dynamic one.

Problem: if the kinematic group take a collision, this collision isn't propagated to the red dynamic rigid body. This is obvious, I can see the collision on kinematic group (in the debug drawer), but I need to handle this one in my own way, just because this is a kinematic object.

Definitively: There is some "workaround" to do this kind of "propagation"? The simple answer is to build the kinematic group as a dynamic chain (multibody or chain of rigidbody) but in this case I can't, I need it to be kinematic.

Best regards,

Dario

User avatar
drleviathan
Posts: 533
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Propagating collisions in a mixed chain Dynamic/Kinematic

Post by drleviathan » Wed Mar 27, 2019 4:34 pm

Why must the blue group be kinematic? Presumably you need it to follow some scripted path.

Perhaps you could use a dynamic RigidBody with a btCompoundShape for the blue group and make it follow the same path close enough via a custom btActionInterface. Since the action would be applied after collisions then hits on the slaved blue group might propagate through to the dynamic object. If transfer of collisions doesn't work very well (I worry that slaving of the blue group might attenuate collision propagation) you could make the action harvest delta velocities from the blue group right before slaving and apply the deltas to the red dynamic.

Dox
Posts: 24
Joined: Thu Oct 18, 2018 5:16 pm

Re: Propagating collisions in a mixed chain Dynamic/Kinematic

Post by Dox » Thu Mar 28, 2019 10:34 am

Hello drleviathan,

thanks for your reply.

I need a kinematic group because I have a complex scene with a lot of physic entities that is really cpu/gpu intensive. If I make the blue group dynamic, I'm not able to stabilize it (even with aggressive solving parameter). With the kinematic/dynamic solution I've reached a good 70% of my goal, because the interaction of kinematic group with others dynamic elements is good (I don't need physical reaction for the kinematic group itself, like constraint break and so on). Unfortunately, the "collision propagation" between kinematic group and the attached dynamic object is important enough, so I need to find a solution (I can accept a not really accurate "collision propagation").

I've tried a "trick" sharing collision shapes between dynamic and kinematic objects. Is difficult to explain, and maybe can be silly, but I try.

1. I build a btCompoundShape for the red dynamic object with the main collision shape (i.e a box).
2. I build the btCollisionShape for each kinematic object, so I build a kinematic btRigidBody via motion state (which hold the relative btCollisionShape).
3. I add the btCollisionShape created in 2 to the btCompoundShape (as child) created in 1. In this situation I should have the same btCollisionShape "shared" by the dynamic btRigidBody (as child of his btCompoundShape) and the kinematic btRigidBody.

Doing that, I can see two collision shapes in my debug drawer, but I think I should see one only (because it should be the same). The shape added to the red dynamic btCompoundShape effectively as collisions, and this is nice. Unfortunately, this seems a "deep copy" of the original one: if I move a kinematic element I can see the relative btCollisionShape movement, but the dynamic btCollisionShape (which should be the same added to the btCompoundShape and the kinematic btRigidBody) doesn't move.

I will try your suggestion, in the meantime if there are other ideas I'll be happy :D

Best regards,

Dario

User avatar
drleviathan
Posts: 533
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Propagating collisions in a mixed chain Dynamic/Kinematic

Post by drleviathan » Fri Mar 29, 2019 3:34 pm

One Shape can be shared across multiple RigidBodies but they only represent the geometry to use in local collision checks, not the world-frame object. The two "collision shapes" you see in your debug rendering are the two RigidBodies which just happen to have the same Shape.

I still don't understand why you can't make a dynamic BlueGroup stable. I believe it is possible if done correctly, assuming you don't actually want your object to pass right through static geometry, which a kinematic object will happily do. Here are some ideas for making a dynamic blue group stable:

(1) Set the mass and inertia tensor on the blue group very high, and then set its velocities to slave to the kinematic path. What is a kinematic object but something with infinite mass + inertia that follows a scripted path? You can approach this same behavior dynamically by making the mass properties artificially high. However, this has the downside of making it difficult to "measure" the collision response on the dynamic object since high mass will tend to attenuate any reactive velocities it might pick up.

(2) A variation on (1) that might work if you don't care about angular dynamics but only linear: use btRigidBody::setAngularFactor(btVector3(0.0, 0.0, 0.0)) to effectively make the inertia tensor infinite and then just tune the linear mass.

When it comes to slaving a dynamic object to a scripted "kinematic" path you just do the following every frame (via a custom btActionInterface):
(a) compute the future scripted transform for next frame
(b) slam the body's velocities such that it will get there in two or three frames (NEVER in one frame because that will introduce an instability)

Naturally this introduces a little bit of lag between where the object is and where it wants to be, however if it is only one or two frames behind and your steps are short then it may be negligible for your purposes. Also there are some details to worry about such as using some "close enough" threshold between the body's real position and its target which is when you slam the velocities to zero. Also, when using this method you definitely want to be using uniform substep duration, limit the number of substeps per frame, and never ever compute part (a) beyond twice your max full-frame step duration. In other words: for absolute stability never use below twice your max full-frame step duration when computing the slaved velocities.

My advice would be to NOT use artificially high mass properties as in (1) and (2) but instead set them to match the RedDynamics masses (assuming BlueGroup is of similar dimensions because if BlueGroup is much larger than RedDynamics you will suffer instabilities if you set its inertia tensor far too small for its size + linear mass). Try that first and only tune to larger mass properties for stability/accuracy if necessary as a last resort.

Dox
Posts: 24
Joined: Thu Oct 18, 2018 5:16 pm

Re: Propagating collisions in a mixed chain Dynamic/Kinematic

Post by Dox » Mon Apr 01, 2019 11:12 am

Hello drleviathan,

first of all, many thanks for your interest and suggestions. You can find details of my problem here:

viewtopic.php?f=9&t=12632

Summarizing the situation, my problem involves 2 entities: a complex dynamic vehicle (the "red one" in this post, that works with several "motors", so a lot of different force application points) and an actuator (the "blue one" in this post) with 9 joints.

At the first try, I have the actuators attached to a fixed point in the world, modeled in 2 different ways: I use the base mass = 0 in case of btMultiBody, or I use a fixed constraint in case of btRigidBody composition (so, any actuator part is a btRigidBody glued with others using constraint like hinge motorized constraint and so on). In BOTH cases, the dynamic vehicle and actuator works fine if NOT attached together! In case of btRigidBody composition, I need to setup an aggressive time step (like 1/500) and high substeps and iterations values (like 50/100) with the sequential impulse solver. In case of btMultiBody I need less aggressive values with mlcp_dantzing solver.

But the problem arise when I attach them together! I've attached the actuator modeled by btRigidBody composition to the dynamic vehicle using a fixed constraint, the same with the btMultiBody (using the "special" fixed constraint that can mix up MultiBody and RigidBody). In both of cases, the actuator start to shake (dantzing) and become unusable. There aren't collisions between entities, because I've filtered them out.

Because this problem, I'm looking for a solution modeling the actuator as Kinematic, but I have the propagation problem described here.

What do you think about this situation?

---

I have to try your last suggestions, but I have a lot of worries...

In case of (1) (infinite mass), I'm worried about the "mass interactions between bodies". If the blue group is a dynamic object with an high mass, I think it will apply an high weight-force to the dynamic red entity, generating a momentum that lead to an unwanted behavior...I'm in wrong?

The case (2) can be interesting, do the "zeroed angular factor" can help to stabilize the solving?

In general, I need to understand well the "scripted kinematic" strategy via btActionInterface. There is some example that can address me in the right way?

Many thanks again for your support,

Best regards,

Dario

User avatar
drleviathan
Posts: 533
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Propagating collisions in a mixed chain Dynamic/Kinematic

Post by drleviathan » Tue Apr 02, 2019 12:40 pm

Yeah, my simplistic idea wouldn't work when the Blue object is a collection of hinged RigidBodies or a MultiBody.

I think you did a good job of listing your options in the other post. I don't have much experience with MultiBody but the path that appeals to me would be (2) where the vehicle and its actuator are one MultiBody. Whenever an actuator is attached to the vehicle you would remove two MultiBodies and add one, and when detaching you would remove one and add two.

Consider the most complex vehicle in your simulation with the most actuators attached at once. If you can simulate that with MultiBody then you should be able to transition to the less complex cases.

steven
Posts: 57
Joined: Mon Nov 05, 2018 8:16 am
Location: China

Re: Propagating collisions in a mixed chain Dynamic/Kinematic

Post by steven » Wed Apr 03, 2019 2:16 am

hi Dox,
i have written a simple case based on the SimpleBox.cpp that can propagate the impulse through the kinematic to all the other objects that collision with this kinematic object. hope it can help you.
this is the code snippet, more details please see the attachment. thanks.

Code: Select all

const btCollisionObject* newContactobA = (specialManifold->getBody0());
const btCollisionObject* newContactobB = (specialManifold->getBody1());
btManifoldPoint& newCp = specialManifold->getContactPoint(0);
for (int i = 0; i < m_thisContacts.size(); i++)
{
	btPersistentManifold* contactManifold = m_thisContacts[i];

	if (contactManifold == specialManifold) continue;

	btManifoldPoint& cp = contactManifold->getContactPoint(0);

	const btCollisionObject* obA = (contactManifold->getBody0());
	const btCollisionObject* obB = (contactManifold->getBody1());
	const btCollisionObject* target = NULL;
	int direct = 1;
	if (obA == bodyKine) { target = obB; direct = -1;  }
	if (obB == bodyKine) { target = obA; direct = 1;   }
	if (target != NULL)
	{
               //apply the impulse to the collision object with KineObj
		btScalar impulse;
		if (newContactobB == bodyKine)
		{
			impulse = (-1)*(newCp.m_normalWorldOnB).dot(cp.m_normalWorldOnB) * direct * newCp.m_appliedImpulse;
		}
		else
		{
			impulse = (newCp.m_normalWorldOnB).dot(cp.m_normalWorldOnB) * direct * newCp.m_appliedImpulse;
		}
		if (impulse == 0) continue;
		const btRigidBody* applyObj = dynamic_cast<const btRigidBody*>(target);
		btRigidBody* applyObj2 = const_cast<btRigidBody*>(applyObj);
		applyObj2->setActivationState(1);
		applyObj2->applyCentralImpulse(cp.m_normalWorldOnB*direct*impulse);
	}
}
Attachments
SimpleBox.cpp
(12.05 KiB) Downloaded 32 times

Dox
Posts: 24
Joined: Thu Oct 18, 2018 5:16 pm

Re: Propagating collisions in a mixed chain Dynamic/Kinematic

Post by Dox » Fri Apr 05, 2019 8:47 am

thank you steven for your example. Best regards.

Post Reply