BulletSliderConstraint usage? Real bug?

G’night,

I’m trying to get a BulletSliderConstraint to work since a few hours. There’s no python example code on the web I could find and the Panda development api reference is naturally not populated yet.
What I have:

boxS = BulletBoxShape(Vec3(.5, .5, .5))
box = BulletRigidBodyNode('Box2')
npBox = render.attachNewNode(box)
npBox.setPos(2, 0, 3)
box.addShape(boxS)
self.world.attachRigidBody(npBox.node())
dbgBox = BulletDebugNode('Debug')
self.world.setDebugNode(dbgBox)
render.attachNewNode(dbgBox).show()

box2S = BulletBoxShape(Vec3(.5, .5, .5))
box2 = BulletRigidBodyNode('box22')
npbox2 = render.attachNewNode(box2)
npbox2.setPos(2, 0, 1)
box2.setMass(5)
box2.addShape(box2S)
self.world.attachRigidBody(npbox2.node())
dbgbox2 = BulletDebugNode('Debug')
self.world.setDebugNode(dbgbox2)
render.attachNewNode(dbgbox2).show()

t1 = TransformState.makePos(npBox.getPos() - (0, 0, .5))
t2 = TransformState.makePos(npbox2.getPos() + (0, 0, .5))
con = BulletSliderConstraint(npBox.node(), npbox2.node(),
                              t1, t2,
                              True)
con.setLowerLinearLimit(0.05)
con.setUpperLinearLimit(1.5)
con.setLowerAngularLimit(0)
con.setUpperAngularLimit(0)
con.setDebugDrawSize(2.0)
#con.enableFeedback(True)
self.world.attachConstraint(con)

This should result in two boxes, about 1 unit above each other, where the lower one should fall down and then hang beneath the first one. What happens is this:

:bullet(error): setWorldTransform: trans is NAN!
(about 20 times)
:bullet(error): setWorldTransform: trans is NAN!
:bullet(error): Overflow in AABB, object removed from simulation
:bullet(error): If you can reproduce this, please email bugs@continuousphysics.com

:bullet(error): Please include above information, your Platform, version of OS.

:bullet(error): Thanks.

As I guess this is rather a bug (if at all) in Panda’s wrapper than Bullet: What might be wrong here? And how does one use sliders (especially these StateTransforms) correctly?

The answer to this is fairly simple: hinge and slider don’t work on linux yet. I’ve asked about them over on the bullet thread:
panda3d.org/forums/viewtopic … &start=300

Right, some of the joints won’t work on Linux. Anyway, this script would perhaps shed some light onto the mystery of slider constraints:

import direct.directbase.DirectStart
from direct.showbase.DirectObject import DirectObject
from panda3d.core import Vec3
from panda3d.core import Point3
from panda3d.core import TransformState
from panda3d.bullet import BulletWorld
from panda3d.bullet import BulletPlaneShape
from panda3d.bullet import BulletRigidBodyNode
from panda3d.bullet import BulletBoxShape
from panda3d.bullet import BulletDebugNode
from panda3d.bullet import BulletSliderConstraint
 
base.setBackgroundColor(0.0, 0.0, 0.6, 1)
base.setFrameRateMeter(True)

base.cam.setPos(0, -20, 0)
base.cam.lookAt(0, 0, 0)
 
# Debug
debugNP = render.attachNewNode(BulletDebugNode('Debug'))
debugNP.show()
debugNP.node().setVerbose(True)

# World
world = BulletWorld()
world.setGravity(Vec3(0, 0, -9.81))
world.setDebugNode(debugNP.node()) 

# Box 1
shape = BulletBoxShape(Vec3(.5, .5, .5))
node = BulletRigidBodyNode('box1')
node.addShape(shape)
np1 = render.attachNewNode(node)
np1.setPos(0, 0, 4)
world.attachRigidBody(np1.node())

# Box 2
shape = BulletBoxShape(Vec3(.3, .3, .3))
node = BulletRigidBodyNode('box2')
node.setMass(1)
node.addShape(shape)
np2 = render.attachNewNode(node)
np2.setPos(0, 0, 2)
world.attachRigidBody(np2.node())

# Slider
t1 = TransformState.makePosHpr(Point3(0, 0, -1), Vec3(0, 0, 45))
t2 = TransformState.makePosHpr(Point3(0, 0, 0), Vec3(0, 0, 0))
con = BulletSliderConstraint(np1.node(), np2.node(), t1, t2, True)
con.setLowerLinearLimit(1)
con.setUpperLinearLimit(8)
world.attachConstraint(con)
 
# Update
def update(task):
  dt = globalClock.getDt()
  world.doPhysics(dt)
  return task.cont

taskMgr.add(update, 'update')
run()

That code is meant to spawn errors, isn’t it? Well, I get some at least.

You get error on Windows? This is strange. I want to have detailed information. If it is Linux then yes, this will get a Bullet error.

Just to note, i am using one of recent buildbot versions on win 7 x64, and snippet works fine.

I’ve asked about this on the bullet forums:
bulletphysics.org/Bullet/phpBB3/ … f=9&t=7254
(No answer yet though)

How dare you to think I’m using Windows? Hehe, just jokin’. I’m using Linux.

How comes this is implemented for Windows only?

Thank you for the effort invested, but I dare say that you won’t get a solution this way. For Bullet users it would be way too complicated to read into the Panda3D code (the would need to understand how PandaNodes work internally!). The most promising thing would be to write a small C++ sample wich reproduces the problem - if there is a problem on the Bullet side at all.

We don’t have different implementation for Windows or Linux (or OSX). The implementation is the same for every OS. It’s just that this code leads to a crash on one OS, and works fine on the other.

I feared that to be the case. So I have to get into Panda’s and Bullet’s cpp interfaces and hack something up. Hope I get it to work in the next days…

I would recommend writing a small C++ console application, which links only with Bullet (no Panda3D stuff). Set up two bodies and a slider like in the sample above, and see print out the transforms of the two bodies for, say, 60 timesteps each 1/60 seconds.

I’ve got a hint already without providing C++ samples.

I found where you initalize the btTransforms in the cpp code (especially [1]), but I cannot judge if it is correct. Does this help you further?

[1] panda3d.cvs.sourceforge.net/view … iew=markup from line 101

Edit: I’ve tried adding np*.setHpr(0, 0, 0) to both boxes in your example, but that doesn’t change things. Additionally, you indeed initialize the TransformStates with makePosHpr…

I’ve built a working piece of C++ that has a slider made of a 6DOF constraint. Works fine: pastebin.com/mYRzFvMU

So there must be some difference between Windows-Python and Linux-Python that bugs us here. This is getting ugly…

Nope. The AABB overflow is the same, no matter if using the C++ API of Panda3D or if using the Python API. Wild guessing doesn’t get us further. I’m working on this issue, but I just have a limited amount of spare time to spend on this hobby, so please be patient.

I didn’t know that.

Of course! :slight_smile:

I finally located the problem and checked in a fix. Please test the next (after today) snapshot build on Linux.

The problem has been that Panda3D Bullet module initially creates rigid bodies with identity transform (when creating a new instance of BulletRigidBodyNode). Changes to the node’s transform (e.g. using np.setPos) are handed on to the wrapped btRigidBody, but Bullet didn’t update the inertia tensor by default. Now I use another method which also updates the inertia tensor.

I’m just curious, why was that only an issue on the linux build? I must have missed something.

To be honest: I don’t know. I just observed this effect.

The constraint seems to work now! (Read: the boxes somehow flick around on startup and no AABB overflow occurs.)

Still, I cannot thoroughly figure out what information the TransformStates convey and how they need to be set up. For example the BulletSliderConstraint: Somewhere I’ve read that each TState specifies to what extent each side of the constraint should be able to move into various directions. But how exactly does that work?