Hi everyone!
First of all, I want to thank you for the great job you are doing with the Bullet Physics library!
I have been using Bullet 2 for many years now, but mostly in python, thanks to a wrapper I found on the internet and I have been maintaining and developing further. Now I am considering moving to PyBullet but I have some questions. I think it is important to say that I just need a physics engine for my project, without the GUI, VR, AI and the new advanced extra features, so I am interested in using the DIRECT mode. The visualization will be done using a 3D engine. I will use the GUI mode just for debugging. I will need to create different kind of single and multi-body objects, using meshes, constraints and create robots and mechanisms. So, as far as I can see in the documentation, there is plenty of useful methods to make all this very easily... But I miss some stuff from Bullet 2, at least looking to the documentation:
1. Have bodyes MotionStates in pyBullet? Or is there any way to get notifications of the objects that are moving? I can have many dynamic objects in a system and need to know which are moving to get the transform and render them.
2. I see that collision filter masks are implemented for shapes, but what happens with ray tests in pybullet? (Batch Tests are a great feature btw.!)
3. I have been using collision callbacks to modify collision points to simulate Conveyor belt-like behavior in some shapes, among other things. I use the CF_CUSTOM_MATERIAL_CALLBACK and the user-data pointer of the shapes that I am interested to provide some "material" information, and then change the behavior of the surface in the callback function. I think that being able to handle material information of the surfaces to modify the manifolds (like friction, damping, contact motion, etc...) brings many possibilities. I do not know if could implement this as a plugin or there is another way to do this kind of things in pybullet...
I think I will need to check pybullet in more detail to get a better idea of the limitations compared to the C++ library. But because I am interested in using it in python I would be happy to help if there is anything I can contribute and bring these features if they can be implemented.
Thanks in advance!
Moving from Bullet 2 to Pybullet
-
- Site Admin
- Posts: 4221
- Joined: Sun Jun 26, 2005 6:43 pm
- Location: California, USA
Re: Moving from Bullet 2 to Pybullet
Yes, the GUI mode is primarily as debug visualizer.
PyBullet has a plugin system (loadPlugin) to customize things.
>> 1. Have bodies MotionStates in pyBullet?
No motion states, but you can write a plugin that gets all notifications of changes, we have some internal plugin for this to notify an external renderer through GRPC. You/we could expose changes to Python, but Python may be not the best choice (a bit slow). I'll see if we can write a default plugin that allows Python to query for the changes since last Python call. The plugin needs to implement a "processNotifications" function, see also the b3PluginManager.cpp for details.
>> ray tests in pybullet?
This is also supposed to happen in a plugin. At the moment, the collisionFilterPlugin only implement a callback if a collision should happen. I need to check if rayTests apply the same filter, we can improve it if not.
>>3. I have been using collision callbacks
This is also a good candidate to write in a C plugin.
Just give PyBullet a try, and dig in the code.
PyBullet has a plugin system (loadPlugin) to customize things.
>> 1. Have bodies MotionStates in pyBullet?
No motion states, but you can write a plugin that gets all notifications of changes, we have some internal plugin for this to notify an external renderer through GRPC. You/we could expose changes to Python, but Python may be not the best choice (a bit slow). I'll see if we can write a default plugin that allows Python to query for the changes since last Python call. The plugin needs to implement a "processNotifications" function, see also the b3PluginManager.cpp for details.
>> ray tests in pybullet?
This is also supposed to happen in a plugin. At the moment, the collisionFilterPlugin only implement a callback if a collision should happen. I need to check if rayTests apply the same filter, we can improve it if not.
>>3. I have been using collision callbacks
This is also a good candidate to write in a C plugin.
Just give PyBullet a try, and dig in the code.
-
- Posts: 24
- Joined: Wed Nov 20, 2013 10:01 am
Re: Moving from Bullet 2 to Pybullet
Thanks for your answer Erwin!
I will definitely give pybullet a try and see if I can learn how to program a plugin. Do you have any documentation or should I check the source code and figure it out?
As I wrote, I will be happy to contribute or help if possible. I leave the link to my old project (I am working on a new platform) so you know which kind of simulation I do: www.simumatik.com.
Thanks, you are great!
Mikel
I will definitely give pybullet a try and see if I can learn how to program a plugin. Do you have any documentation or should I check the source code and figure it out?
As I wrote, I will be happy to contribute or help if possible. I leave the link to my old project (I am working on a new platform) so you know which kind of simulation I do: www.simumatik.com.
Thanks, you are great!
Mikel
-
- Posts: 24
- Joined: Wed Nov 20, 2013 10:01 am
Re: Moving from Bullet 2 to Pybullet
Hi Erwin!
I have been using pybullet for some days now and I would like to start implementing the plugins we discussed above:
- Motion states.
- Collision filters for ray tests.
- Using Custom materials.
Can you help me to get started? Any document that explains how to introduce new plugins?
Thanks in advance!
Mikel
I have been using pybullet for some days now and I would like to start implementing the plugins we discussed above:
- Motion states.
- Collision filters for ray tests.
- Using Custom materials.
Can you help me to get started? Any document that explains how to introduce new plugins?
Thanks in advance!
Mikel
-
- Site Admin
- Posts: 4221
- Joined: Sun Jun 26, 2005 6:43 pm
- Location: California, USA
Re: Moving from Bullet 2 to Pybullet
>> The visualization will be done using a 3D engine.
>> - Motion states.
Is your 3d engine also Python or C++?
How do you want to synchronize the graphics transforms? Through C++ / shared memory, or using Python?
If it happens in Python, we could add a method that receives only the updated objects. Then no plugin is needed.
For the ray cast, we can add a flag to also apply collision filters. It has to be implemented in PhysicsServerCommandProcessor.
Same for custom materials. PyBullet allows custom properties, that could be useful.
>> - Motion states.
Is your 3d engine also Python or C++?
How do you want to synchronize the graphics transforms? Through C++ / shared memory, or using Python?
If it happens in Python, we could add a method that receives only the updated objects. Then no plugin is needed.
For the ray cast, we can add a flag to also apply collision filters. It has to be implemented in PhysicsServerCommandProcessor.
Same for custom materials. PyBullet allows custom properties, that could be useful.
-
- Posts: 24
- Joined: Wed Nov 20, 2013 10:01 am
Re: Moving from Bullet 2 to Pybullet
Hi Erwin,
Right now I would prefer to use Python to interface the physics engine. If we see any performance issue we could move to C++. I think it is great to have the option to run the physics server in another computer, so I guess shared memory/C++ is not an option...
- Motion States: A method that we could call after the simulation step to receive the updated objects and their transform (pos, quat) would be great. Right now we are crawling all the objects after some steps instead (60 fps).
- Custom materials: Before I had my own python wrapper that I could share with you if you want. This is what I was doing:
1. Add in the constructor of btDiscreteDynamicsWorld():
gContactAddedCallback = CustomMaterialCombinerCallback;
2. To simulate conveyor like surfaces, I linked a custom material to some user pointers:
3. Finally, this was the implementation of the callback
- RayTests: If both the simple and batch could have the collision flag for each test would be great. In addition, I had some extra RayTest methods to get not just if a collision happens but even distance (simulates a laser sensor) or collided object index, useful to simulate for example an RFID antenna and then get user data (RFID data) from the collided object.
Some more code that shows that:
Thank you very much for your time. Let me know how I can help you to get all this inside pybullet. Would be great to use it in the new emulation platform we are developing now.
If you want more details you can send me a private or contact by email.
//Mikel
Right now I would prefer to use Python to interface the physics engine. If we see any performance issue we could move to C++. I think it is great to have the option to run the physics server in another computer, so I guess shared memory/C++ is not an option...
- Motion States: A method that we could call after the simulation step to receive the updated objects and their transform (pos, quat) would be great. Right now we are crawling all the objects after some steps instead (60 fps).
- Custom materials: Before I had my own python wrapper that I could share with you if you want. This is what I was doing:
1. Add in the constructor of btDiscreteDynamicsWorld():
gContactAddedCallback = CustomMaterialCombinerCallback;
2. To simulate conveyor like surfaces, I linked a custom material to some user pointers:
Code: Select all
class btCustomMaterial{
// Custom material class. If attached as userpointer to a CollisionObject (body), it makes possible to modify the contact point behaviour
public:
btVector3 m_lateralFrictionDir1; //Lateral friction 1
btScalar m_contactMotion1; //Motion speed for lateral friction 1
int m_useCounter1; //For debuging
int m_useCounter2; //For debuging
btCustomMaterial()
{
m_lateralFrictionDir1.setValue(0.f,0.f,0.f);
m_contactMotion1 = 0.f;
m_useCounter1 = 0;
m_useCounter2 = 0;
}
void setMotionSpeed (btScalar speed)
{
m_contactMotion1 = speed;
}
void setMotion (btVector3& direction, btScalar speed)
{
m_lateralFrictionDir1 = direction;
m_contactMotion1 = speed;
}
int getUse1()
{
return m_useCounter1;
}
int getUse2()
{
return m_useCounter2;
}
};
Code: Select all
static bool CustomMaterialCombinerCallback(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1)
{
// Find material to modify cp
btCustomMaterial* material = NULL;
// object with custom material
const btCollisionObject* obj;
// Check if Object 0 has custom material (Usually this is executed)
obj = colObj0Wrap->getCollisionObject();
material = (btCustomMaterial*) obj->getUserPointer();
if (material != NULL)
{
// Motion Friction Speed
cp.m_lateralFrictionInitialized = true;
// Motion Friction Direction
cp.m_lateralFrictionDir1 = quatRotate(obj->getWorldTransform().getRotation(), material->m_lateralFrictionDir1);
cp.m_contactMotion1 = - material->m_contactMotion1;
cp.m_lateralFrictionDir2 = cp.m_lateralFrictionDir1.cross(cp.m_normalWorldOnB);
material->m_useCounter1 ++;
return true;
}
// If not, has Object 1 custom material?
obj = colObj1Wrap->getCollisionObject();
material = (btCustomMaterial*) obj->getUserPointer();
if (material != NULL)
{
cp.m_lateralFrictionInitialized = true;
// Motion Friction Direction
cp.m_lateralFrictionDir1 = quatRotate(obj->getWorldTransform().getRotation(), material->m_lateralFrictionDir1);
cp.m_contactMotion1 = material->m_contactMotion1;
cp.m_lateralFrictionDir2 = cp.m_lateralFrictionDir1.cross(cp.m_normalWorldOnB); //is it ok?
material->m_useCounter2 ++;
return true;
}
return false;
}
Some more code that shows that:
Code: Select all
static bool btRayTestHit(btCollisionWorld* world, const btVector3& rayFrom, const btVector3& rayTo, short int collisionmask, short int collideswithmask)
{
// Start and End are vectors
btCollisionWorld::ClosestRayResultCallback RayCallback(rayFrom, rayTo);
// Perform raycast
world->rayTest(rayFrom, rayTo, RayCallback);
// Test results
if (RayCallback.hasHit())
{
// Check collision filter
return (RayCallback.m_collisionObject->getBroadphaseHandle()->m_collisionFilterGroup & collideswithmask) && (collisionmask & RayCallback.m_collisionObject->getBroadphaseHandle()->m_collisionFilterMask);
}
// None hit
return false;
}
static float btRayTestDist(btCollisionWorld* world, const btVector3& rayFrom, const btVector3& rayTo, short int collisionmask, short int collideswithmask)
{
// Start and End are vectors
btCollisionWorld::ClosestRayResultCallback RayCallback(rayFrom, rayTo);
// Perform raycast
world->rayTest(rayFrom, rayTo, RayCallback);
// Test results
if (RayCallback.hasHit())
{
// Check collision filter
if ((RayCallback.m_collisionObject->getBroadphaseHandle()->m_collisionFilterGroup & collideswithmask) && (collisionmask & RayCallback.m_collisionObject->getBroadphaseHandle()->m_collisionFilterMask))
{
return rayFrom.distance(RayCallback.m_hitPointWorld);
}
}
// None hit
return -1.f;
}
static int btRayTestObjIndex(btCollisionWorld* world, const btVector3& rayFrom, const btVector3& rayTo, short int collisionmask, short int collideswithmask)
{
// Start and End are vectors
btCollisionWorld::ClosestRayResultCallback RayCallback(rayFrom, rayTo);
// Perform raycast
world->rayTest(rayFrom, rayTo, RayCallback);
// Test results
if (RayCallback.hasHit())
{
// Check collision filter
if ((RayCallback.m_collisionObject->getBroadphaseHandle()->m_collisionFilterGroup & collideswithmask) && (collisionmask & RayCallback.m_collisionObject->getBroadphaseHandle()->m_collisionFilterMask))
{
return RayCallback.m_collisionObject->getUserIndex();
}
}
// None hit
return -1;
}
If you want more details you can send me a private or contact by email.
//Mikel
-
- Posts: 1
- Joined: Tue Jan 28, 2020 1:05 pm
Re: Moving from Bullet 2 to Pybullet
Hello,
I am currently also trying to simulate conveyors in PyBulllet.
Has there been any update on this? How, can I implement the CustomMaterialCombinerCallback, when using PyBullet?
Thanks and best
I am currently also trying to simulate conveyors in PyBulllet.
Has there been any update on this? How, can I implement the CustomMaterialCombinerCallback, when using PyBullet?
Thanks and best