Physics Simulation Forum

 

All times are UTC




Post new topic Reply to topic  [ 8 posts ] 
Author Message
PostPosted: Mon Oct 09, 2017 8:36 am 
Offline
User avatar

Joined: Fri Feb 19, 2016 2:04 am
Posts: 8
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/viewtopic.php?t=6076#p21441
http://bulletphysics.org/Bullet/phpBB3/viewtopic.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? :roll:


Top
 Profile  
 
PostPosted: Mon Oct 09, 2017 3:52 pm 
Offline
User avatar

Joined: Tue Sep 30, 2014 6:03 pm
Posts: 346
Location: San Francisco
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.


Top
 Profile  
 
PostPosted: Mon Oct 09, 2017 9:48 pm 
Offline
User avatar

Joined: Fri Feb 19, 2016 2:04 am
Posts: 8
drleviathan wrote:
You modulate it by actually setting its velocity, and you can set its magnitude to be as long as you like.

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:
Code:
      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
      }


Is this the right way to do it?


Top
 Profile  
 
PostPosted: Tue Oct 10, 2017 1:03 am 
Offline
User avatar

Joined: Tue Sep 30, 2014 6:03 pm
Posts: 346
Location: San Francisco
No, I think the most important part is that you add the track as a kinematic object:
Code:
body->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT);
world->addRigidBody(body);

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:
body->setLinearVelocity(velocity);
body->activate();


Top
 Profile  
 
PostPosted: Tue Oct 10, 2017 6:55 am 
Offline
User avatar

Joined: Fri Feb 19, 2016 2:04 am
Posts: 8
drleviathan wrote:
No, I think the most important part is that you add the track as a kinematic object:
Code:
body->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT);
world->addRigidBody(body);

[/code]

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.


Top
 Profile  
 
PostPosted: Tue Oct 10, 2017 12:29 pm 
Offline
User avatar

Joined: Tue Sep 30, 2014 6:03 pm
Posts: 346
Location: San Francisco
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.


Top
 Profile  
 
PostPosted: Wed Oct 11, 2017 6:51 am 
Offline
User avatar

Joined: Fri Feb 19, 2016 2:04 am
Posts: 8
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.


Top
 Profile  
 
PostPosted: Wed Oct 11, 2017 1:33 pm 
Offline
User avatar

Joined: Tue Sep 30, 2014 6:03 pm
Posts: 346
Location: San Francisco
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.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 15 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group