Applying force on compound bodies

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
Shakaron
Posts: 6
Joined: Mon Feb 25, 2008 3:18 pm

Applying force on compound bodies

Post by Shakaron »

Hi, guys!

I try to get familiar with video game development and I chose BepuPhysics for this purpose since I would use XBOX 360 as a platform. Though the current development is on Windows x86.
I have a tank. It is a compound body of 3 boxes: hull, turret and a gun. These boxed do not intersect each other. When I put them together, they form the desired tank. That’s nice. But a tank should move, right? I take a force, and tell the compound body, to apply this force on itself. When the tank is still in the air, it just flies away but as soon as landing on the height map it won’t move an inch any more. The mass of the compound body is 62 kg (I tried 62000 kg first, since it would be realistic, then just stick to the one thousands part of it reading something about too much mass could cause problems). The force applied to the compound body is
Force force = new Force (Vector3.Zero, new Vector3 (0f, 0f, -1e2f), 0f));
Increased beyond a certain level (1e10) the program would just freeze.

Any of you could give me some hint what the problem could be? Why won’t the tank move after being on the height map / static box (like a table).

Thanks for any help or advice!

Cheers,
Shakaron
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Applying force on compound bodies

Post by Norbo »

How large is the tank? Very large objects (hundreds or thousands of units across) can sometimes act oddly.

Otherwise, it should work fine given a good force/impulse. A 100 newton force could have issues overcoming the default friction force on a 62 kilogram object, and a 10,000,000,000 newton force would send it flying into infinity pretty quick (the engine doesn't enjoy this much). Have you tried something like 1000 newtons on a 62 kilogram object? Friction can also be changed through the entity.staticFriction and entity.dynamicFriction fields.

Without any other changes, you will notice that the force doesn't follow the tank around so it will begin to impart a high angular velocity on the object. The force can be made into a 'thruster' of sorts by putting its initial position on the tank somewhere and then setting force.isTrackingTarget = true.

If the object still appears to freeze on impact, try putting another box in the simulation to see if its just the compound body or if it's the whole simulation seizing up.
Shakaron
Posts: 6
Joined: Mon Feb 25, 2008 3:18 pm

Re: Applying force on compound bodies

Post by Shakaron »

Hi, Norbo!

I tried the forces from 10 to 1e12 by the factor of ten. Did not change any friction but enabled the "thruster" feature...

Here is a part of the code of the constructor of the tank:

Vector3 originalPosition = new Vector3 (0f, 10f, 0f);
CompoundBody body = new CompoundBody ();
// Creating the hull
Vector3 position = originalPosition;
Box hull = new Box (position, 3.7f, 1.2f, 8f, 46.900f);
// Creating the turret
position = originalPosition;
Vector3 turretPositionCorrection = new Vector3 (0f, 1.21f, 0f);
Box turret = new Box (position + turretPositionCorrection, 3.3f, 0.8f, 4.5f, 16.750f);
// Creating the gun
Vector3 gunPositionCorrection = new Vector3 (0f, 1.2f, -4.11f);
Box gun = new Box (position + gunPositionCorrection, 0.13f, 0.13f, 4.1f, 3.350f);

body.addBody (hull);
body.addBody (turret);
body.addBody (gun);

physicalModel = body; // Physical body is a protected member of the super class of type Entity.

Vector3 centPos = physicalModel.centerPosition;
ector3 pos = physicalModel.centerOfMass;

// The tank could be driven by two engines: the left and the right one
rightEngine = new Force (Vector3.Zero, new Vector3(0f, 0f, -1f) * 60000, 2000f);
leftEngine = new Force (Vector3.Zero, new Vector3 (0f, 0f, -1f) * 60000, 2000f);
hull.applyForce (rightEngine);
hull.applyForce (leftEngine);
rightEngine.isTrackingTarget = true;
leftEngine.isTrackingTarget = true;


And here I try desperately giving some force to the tank just ot move...

public void RightEngine (float power)
{
((CompoundBody) physicalModel).applyForce(new Force(Vector3.Zero, new Vector3(0f, 0f, -1e3f), 0f)); // casting makes no different. I just left it there...
}


The funny thing is that if I remove the other objects from the body leaving the hull alone the tank would move on the ground. As if something would go wrong when a compound body is *really* a compound body, not just a wrapper for a solo entity... So if I just add that "tiny" :-) gun to the compound body next to the hull the tank would not get moved any more...

By the way I know that applying a new force to the body won't follow it, just the original one. I just wanted the compound body to move so badly. :P I really don't understand what's going on. :-S

It should work right? And it does if there is only one entity in the compound body but if there are more than the solo one... And if the compound body consists more objects and has no connection to the ground it works again... What do I wrong? Gravity is realistic: 9.81 (Like here in Europe).

Tank:
dynamic friction: 0.3
static friction: 0.6

Terrain:
friction: 0.5

By the way: the tank (physicalModel in my code) is not among the updatables of the space. Only in the list of entities. Thats OK, right?

And about the 'thruster' force: should I give the center position of the Force vector in world coordinates right? I suppose I should. And yes, I know. In my code it is not inside the tank. :-)

Thanks for the help!

Cheers,
Shakaron
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Applying force on compound bodies

Post by Norbo »

In your construction area, the forces are applied to the hull subbody rather than the compound body parent. Changing the hull.applyForce to body.applyForce should fix that problem. I also toned down the force magnitude and added the compound body and a ground object to the space. Here's the very slightly modified version of the code that I tested successfully:

Code: Select all

                    Vector3 originalPosition = new Vector3(0f, 10f, 0f);
                    CompoundBody body = new CompoundBody();
                    // Creating the hull
                    Vector3 position = originalPosition;
                    Box hull = new Box(position, 3.7f, 1.2f, 8f, 46.900f);
                    // Creating the turret
                    position = originalPosition;
                    Vector3 turretPositionCorrection = new Vector3(0f, 1.21f, 0f);
                    Box turret = new Box(position + turretPositionCorrection, 3.3f, 0.8f, 4.5f, 16.750f);
                    // Creating the gun
                    Vector3 gunPositionCorrection = new Vector3(0f, 1.2f, -4.11f);
                    Box gun = new Box(position + gunPositionCorrection, 0.13f, 0.13f, 4.1f, 3.350f);

                    body.addBody(hull);
                    body.addBody(turret);
                    body.addBody(gun);

                    Entity physicalModel = body; // Physical body is a protected member of the super class of type Entity.

                    Vector3 centPos = physicalModel.centerPosition;
                    Vector3 pos = physicalModel.centerOfMass;

                    // The tank could be driven by two engines: the left and the right one
                    Force rightEngine = new Force(Vector3.Zero, new Vector3(0f, 0f, -1f) * 60, 2000f);
                    Force leftEngine = new Force(Vector3.Zero, new Vector3(0f, 0f, -1f) * 60, 2000f);
                    body.applyForce(rightEngine);
                    body.applyForce(leftEngine);
                    rightEngine.isTrackingTarget = true;
                    leftEngine.isTrackingTarget = true;

                    space.add(body); //add the compound body to the space

                    space.add(new Box(Vector3.Zero, 50, 1, 50)); //Create the ground
Shakaron
Posts: 6
Joined: Mon Feb 25, 2008 3:18 pm

Re: Applying force on compound bodies

Post by Shakaron »

Hi, Norbo!

I made the adjustments you suggested. The result is still disappointing.

The thing is that you add the force to the tank before it hits the ground so it already has an impulse and starts moving still being in the air. (Sorry for my bad English, I seem not been capable to state that clearly that my version of tank moved in the air as well. And continued that movement on the ground since had an "initial" impulse...

But what happens when you move the appliance of the force to a function like I would like to do? Would you have a couple of minute for checking on my code? I could put on the Internet or send in a main a zip file containing all the project. You could try it yourself. If you don't have an XBOX controller attached to your computer (but you should since BepuPhysics is for XNA and XBOX 360 :D) then I could change the controls. :-P

I could point out where and what to check on, don't have to go through thousand of line of codes. :P

And if you don't have resources for these kinda problems/requests, could you wait in your working version? Wait until the tank hits the ground (and stops buouncing... while bouncing a little bit my tank stars as well. But after that... :-S)

I'm in Central Europe. And the time is almost 2 a.m. here. :-P I've gotta go to bed soon. School and working hours start soon and I'm tired like hell. ;)

Cheers,
Shakaron
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Applying force on compound bodies

Post by Norbo »

I think I might know what is happening. Applying a force doesn't wake up a sleeping object, and while asleep, the object will not have the force applied to it. Your tank lands on the ground and gets itself situated for a nap since the initial forces aren't strong enough to keep it scooting around and awake. Then, when you apply numerous new forces, nothing appears to happen since the object is sleeping. This can also explain why, when only one object was used, the compound didn't go to sleep; it was lighter and the force was barely able to keep it awake.

A quick test for this would be to either use entity.activate() when you're adding a new force or to set entity.isAlwaysActive = true for the compound body.

Just for a little general information, you can also use impulses instead of forces (applyImpulse, applyLinearImpulse, applyAngularImpulse). The object has to be active for them to have a visible effect, but the applyImpulse method activate them internally if desired. The Vehicle class can also be used to do the heavy lifting for a more 'realistic' simulation. A tank could be simulated by multiple wheels on each side representing the treads, and steering could be accomplished by just accelerating in one direction with one tread and in the opposite direction on the other tread.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Applying force on compound bodies

Post by Norbo »

Regarding a couple of the last questions in your previous post:
By the way: the tank (physicalModel in my code) is not among the updatables of the space. Only in the list of entities. Thats OK, right?
Yes, the updateables list is a separate list of extra 'plugged in' objects, like force fields, static triangle groups, etc. that the space is asked to manage. Entities will all go into the entity list when space.add(Entity) is used.
And about the 'thruster' force: should I give the center position of the Force vector in world coordinates right? I suppose I should. And yes, I know. In my code it is not inside the tank.
Yes, that'll keep it from causing spazzy spinouts.

Additionally (if the above method doesn't work), when you were using very high force values (>1e3), did the tank fly off the screen rapidly or did it seem to do nothing different and settle down in the same manner as ever, and were those forces the forces applied initially to subbodies or the one applied later using input to the compound body itself?
Shakaron
Posts: 6
Joined: Mon Feb 25, 2008 3:18 pm

Re: Applying force on compound bodies

Post by Shakaron »

Hey, Norbo!
Norbo wrote:Additionally (if the above method doesn't work), when you were using very high force values (>1e3), did the tank fly off the screen rapidly or did it seem to do nothing different and settle down in the same manner as ever, and were those forces the forces applied initially to subbodies or the one applied later using input to the compound body itself?
Applying a high force on the tank made it fly away. Increasing the intensity of the force made the impulse much intense (as could be expected). At some point the object just "disappeared". :-) It were not the initial forces applied on the hull but those applied later on the compound body by pressing the "move" button. Later on in my code I added an "isEngineOn" boolean property to prevent applying an engine force 457 times. :P

Today I'll try to remove all the frictions and see whan happens then... I'm in the office right now, I just shouldn't play around with my school work here. :lol:

Have a nice day!
--
Shakaron
Shakaron
Posts: 6
Joined: Mon Feb 25, 2008 3:18 pm

Re: Applying force on compound bodies

Post by Shakaron »

Norbo wrote:A quick test for this would be to either use entity.activate() when you're adding a new force or to set entity.isAlwaysActive = true for the compound body.
Thanks! It seems to be the problem. I'll try it when I get home (or to school).
Norbo wrote:Just for a little general information, you can also use impulses instead of forces (applyImpulse, applyLinearImpulse, applyAngularImpulse). The object has to be active for them to have a visible effect, but the applyImpulse method activate them internally if desired.
Yeah, applyImpulse worked on the tank. But my consultant/research fellow at school (sorry, I don't know the exact phrase) suggested that we should use forces not impulses. So we just stick to the forces.
Norbo wrote:The Vehicle class can also be used to do the heavy lifting for a more 'realistic' simulation. A tank could be simulated by multiple wheels on each side representing the treads, and steering could be accomplished by just accelerating in one direction with one tread and in the opposite direction on the other tread.
We did take the Vehicle class under short consideration as well. For the first approach we thought just a sliding bunch of objects (let's call it a compound body :)) would do the trick. Later on we could switch if necesarry. Thanks for the support though. I'm sure sooner or later I'll change the physics model of the tank to the Vehicle class. (I have close deadlines, and hardly have time to anything. :? )

Thanks for all the help! I'll let you know about the results!

Cheers,
Shakaron
Shakaron
Posts: 6
Joined: Mon Feb 25, 2008 3:18 pm

Re: Applying force on compound bodies

Post by Shakaron »

Hi, Norbo!

I had a little time last night but successfully tested the application with the activation of the compound body when applying the forces on it. So it was really the sleeping of the compound body that caused the problem.

Thank you for all of your help!

Cheers,
Shakaron
doggan
Posts: 20
Joined: Fri Jan 09, 2009 9:26 pm

Re: Applying force on compound bodies

Post by doggan »

Hey Norbo - sorry to bump an old thread, but it seems I have the same problem!

I've got a compound body composed of a few cylinders. The combined mass of the sub bodies is 500. The player is able to shoot this compound body and it will react (imagine a weight swinging on the end of a rope, and then shooting the weight). The weight is hooked to a BallSocketJoint to get a swinging behavior.

This was working perfectly using just a single Box and using applyImpulse() to the box. I now need a more accurate collision, so I switched to the compound body containing cylinders.

It seems that the compound body is sleeping. I have set isAlwaysActive = true. I've tried calling activate() before/after applyImpulse. I've tried changing the linearMomentum directly. The body still sleeps before coming back to it's rest position.

If I physically run into the weight with the player capsule, the weight responds properly and continues swinging.

Any ideas as to what is happening?

Edit: Hmm.. it seems like lowering the mass of my sub-bodies allows it to work somewhat. It is still extremely unstable, though. For example, I shoot it twice and it moves slightly and comes to a halt (w/o returning to the proper rest state), and then I shoot it a 3rd time and it goes flying around the joint at super-speed.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Applying force on compound bodies

Post by Norbo »

A few information gathering questions to start:

When it is moving, does it appear to move correctly and continuously as opposed to jerkily or with a strange constant motion before suddenly stopping?

After you bumped it with a character, did you move away from the object to let it swing freely or did the character stay nearby (close enough to create a collision controller between the objects due to bounding box intersection)?

When you are applying impulses and setting flags, are you interacting with the CompoundBody parent or are you interacting with the subbodies? All of the interactions should be with the CompoundBody parent.
doggan
Posts: 20
Joined: Fri Jan 09, 2009 9:26 pm

Re: Applying force on compound bodies

Post by doggan »

- Once it gets passed a certain 'threshold' impulse, it moves nice and smoothly. The first few shots will bump the weight slightly, but it won't return to it's resting position. It just sort of hangs there at an angle, which disobeys the force of gravity :)

- Both work perfectly. I can either bump it and move out of the way and it swings perfectly. Or I can stand at it's resting point and it will rotate around the player.

- Applying to the compound body.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Applying force on compound bodies

Post by Norbo »

If it's a pretty large object, you might be seeing the angular velocity threshold which can be readjusted using space.simulationSettings.angularVelocityClamping and space.simulationSettings.angularVelocityClampingTime.

Of course this assumes that the boost given by the character was larger than your bullets, and doesn't explain the super speed issue.
doggan
Posts: 20
Joined: Fri Jan 09, 2009 9:26 pm

Re: Applying force on compound bodies

Post by doggan »

Thanks for the feedback. It seems I had two problems:

- I adjusted the Clamping/ClampingTime parameters. This stopped the object from halting.
- The super speed issue was due to a 'normal' vector being used, which was not actually normalized. I assumed the hit normals returned from the raycast function were already normalized, but I guess not in this case :)

Thanks again.
Post Reply