Hello, I'm trying to make a tracked vehicle, like tank, in Bullet. And for the tracks, I decide to use friction model.
The code is much more the same as the post discussed here:
http://bulletphysics.org/Bullet/phpBB3/ ... 076#p21441
http://bulletphysics.org/Bullet/phpBB3/ ... php?t=6730
But the problem is, the friction motion seems to have a maximum value of 10. No matter how big value the variable m_contactMotion1 is set, the object can only reach the speed of the maximum of 10.
Like in my game when I set the tank speed to 20, and it can only run at the highest speed of 10.
And suggestions?
Conveyor belt speed problem (using friction model)
-
- Posts: 10
- Joined: Fri Feb 19, 2016 2:04 am
-
- Posts: 849
- Joined: Tue Sep 30, 2014 6:03 pm
- Location: San Francisco
Re: Conveyor belt speed problem (using friction model)
You don't modulate the velocity of the "conveyor" by adjusting the friction coefficient. You modulate it by actually setting its velocity, and you can set its magnitude to be as long as you like.
The way to make a conveyor is to create a "kinematic" object that isn't actually moving. That is, you don't actually allow its WorldTransform to change over time, but you nevertheless give it a non-zero velocity. When dynamic objects collide with the conveyor the ContactPoint uses the non-zero velocity of the conveyor to push the dynamic objects as if the surface of the conveyor is moving.
The friction coefficient merely determines the maximum ratio of the magnitude of the friction force over that of the normal force.
The way to make a conveyor is to create a "kinematic" object that isn't actually moving. That is, you don't actually allow its WorldTransform to change over time, but you nevertheless give it a non-zero velocity. When dynamic objects collide with the conveyor the ContactPoint uses the non-zero velocity of the conveyor to push the dynamic objects as if the surface of the conveyor is moving.
The friction coefficient merely determines the maximum ratio of the magnitude of the friction force over that of the normal force.
-
- Posts: 10
- Joined: Fri Feb 19, 2016 2:04 am
Re: Conveyor belt speed problem (using friction model)
I see. So now instead of modify the friction, I calculate the forward direction vector on contact point and set the velocity on it. Below is my code:drleviathan wrote:You modulate it by actually setting its velocity, and you can set its magnitude to be as long as you like.
Code: Select all
btVector3 minDir;//forward direction of closest contact point
float t_speed = core::abs_(m_speed);//m_speed is current track speed (negative means backwards)
for (int j = 0; j < pm->getNumContacts(); j++)
{
btManifoldPoint& point = pm->getContactPoint(j);
point.m_lateralFrictionInitialized = true;
point.m_lateralFrictionDir1.setValue(dir.X, dir.Y, dir.Z);//dir is current forward direction of track object
//point.m_lateralFrictionDir1.normalize(); comment this line because dir is already normalized before in my code
point.m_contactMotion1 = 2;
point.m_combinedFriction = 9;
point.m_combinedRestitution = combinedRestitution;
if (abs_(point.m_distance1) < min_distance)
{
//find closet contact point
min_distance = abs_(point.m_distance1);
btVector3 herizonLeft = point.m_lateralFrictionDir1.cross(
point.m_normalWorldOnB);
//calculate forward direction of contact point
minDir = point.m_normalWorldOnB.cross(herizonLeft);
}
}
//set velocity
if (pm->getNumContacts() > 0)
{
btVector3 vel_new = t_speed * minDir;
bt_rigidbody->setLinearVelocity(vel_new);//rigidbody is track itself
}
-
- Posts: 849
- Joined: Tue Sep 30, 2014 6:03 pm
- Location: San Francisco
Re: Conveyor belt speed problem (using friction model)
No, I think the most important part is that you add the track as a kinematic object:
Then whenever you change its velocity make sure it is active so that it will wake up any inactive dynamic objects that might be touching it.
Code: Select all
body->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT);
world->addRigidBody(body);
Code: Select all
body->setLinearVelocity(velocity);
body->activate();
-
- Posts: 10
- Joined: Fri Feb 19, 2016 2:04 am
Re: Conveyor belt speed problem (using friction model)
I think you get me wrong. What I want do is to make a inverse conveyor belt. Rather than move other objects, it should be able to move itself like a tank's track.drleviathan wrote:No, I think the most important part is that you add the track as a kinematic object:[/code]Code: Select all
body->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT); world->addRigidBody(body);
-
- Posts: 849
- Joined: Tue Sep 30, 2014 6:03 pm
- Location: San Francisco
Re: Conveyor belt speed problem (using friction model)
Ah yes, I did misunderstand. I don't know how to do exactly what you're trying. The only ideas I have to offer are:
(1) It might be possible to make a real tank tread using the multi-body stuff. I don't have much more to offer here except that it would probably require small substeps like the next idea:
(2) A multi-wheel tank approximation might be possible using rows of wheels connected with motorized constraints, say 4 or 5 wheels on a side. One problem with this is: when you have lots of constraints in one connected system you need small timesteps. You'd probably need to substep the simulation at 200Hz or higher. I've personally seen 4 wheel robots work with pure Bullet physics (stepped at 240Hz).
(3) You could use the btRaycastVehicle and fake tread friction.
(1) It might be possible to make a real tank tread using the multi-body stuff. I don't have much more to offer here except that it would probably require small substeps like the next idea:
(2) A multi-wheel tank approximation might be possible using rows of wheels connected with motorized constraints, say 4 or 5 wheels on a side. One problem with this is: when you have lots of constraints in one connected system you need small timesteps. You'd probably need to substep the simulation at 200Hz or higher. I've personally seen 4 wheel robots work with pure Bullet physics (stepped at 240Hz).
(3) You could use the btRaycastVehicle and fake tread friction.
-
- Posts: 10
- Joined: Fri Feb 19, 2016 2:04 am
Re: Conveyor belt speed problem (using friction model)
Thanks for advice. Multiple objects solution seems great for single tank simulation. However cause this is a game, it's hard to keep a nice frame rate while simulate multiple, at least 10 tanks.
After tried ray cast vehicle, I think make conveyor a rigidbody may be a moderate solution.
After tried ray cast vehicle, I think make conveyor a rigidbody may be a moderate solution.
-
- Posts: 849
- Joined: Tue Sep 30, 2014 6:03 pm
- Location: San Francisco
Re: Conveyor belt speed problem (using friction model)
I just had another idea that uses collision groups:
(A) Each tank is put into a special collision group. TankGroup collides with everything, including ConveyorGroup.
(B) ConveyorGroup collides with nothing except TankGroup.
(C) Each tank gets two conveyors, one for each tread. A conveyor has a flat surface shaped like a tank tread and rests under its corresponding tank tread. It is a separate RigidBody from the tank, but is kinematic and follows the tank around as described below.
(D) Every substep, before the integration part, you transform each tread to lie directly below its corresponding tread. You give each conveyor the correct linear velocity according to its tread's speed.
(E) During the integration part of the simulation the contacts between the conveyors and the tank will push the tank forward as if it were on tracks. This will move the tank off of the conveyor, but only a little bit and the conveyor will follow the tank before the next substep.
In short, use kinematic conveyors that follow the tanks around like private Jacob's ladders.
One gotcha with this method is that you can't actually reposition the conveyors based on nothing but the tank's transform. Floating point error and recursive transform calculations will cause drift and the conveyors will eventually push the tanks into the air or worse (NaN). However, if you know how high the conveyors should be (that is, you know the height of the ground under the tank) then you could clamp their transforms such that their top surface is just above the ground. The tanks will "fall" onto the conveyors and the recursive transform drift problem will be solved.
(A) Each tank is put into a special collision group. TankGroup collides with everything, including ConveyorGroup.
(B) ConveyorGroup collides with nothing except TankGroup.
(C) Each tank gets two conveyors, one for each tread. A conveyor has a flat surface shaped like a tank tread and rests under its corresponding tank tread. It is a separate RigidBody from the tank, but is kinematic and follows the tank around as described below.
(D) Every substep, before the integration part, you transform each tread to lie directly below its corresponding tread. You give each conveyor the correct linear velocity according to its tread's speed.
(E) During the integration part of the simulation the contacts between the conveyors and the tank will push the tank forward as if it were on tracks. This will move the tank off of the conveyor, but only a little bit and the conveyor will follow the tank before the next substep.
In short, use kinematic conveyors that follow the tanks around like private Jacob's ladders.
One gotcha with this method is that you can't actually reposition the conveyors based on nothing but the tank's transform. Floating point error and recursive transform calculations will cause drift and the conveyors will eventually push the tanks into the air or worse (NaN). However, if you know how high the conveyors should be (that is, you know the height of the ground under the tank) then you could clamp their transforms such that their top surface is just above the ground. The tanks will "fall" onto the conveyors and the recursive transform drift problem will be solved.