btRigidBody motion state null error

barragan
Posts: 3
Joined: Sun Mar 03, 2013 5:52 am

btRigidBody motion state null error

Post by barragan »

Hi everyone,

I posted something similar earlier but have been tracking down the weirdness and now have more insight. But I still have a question on what is going on and thus am reposting.

So the backstory:

I have been trying to get a ROS package to work with bullet 2.81. ROS has an older version of bullet in it which doesn't have everything I want. Thus the attempted upgrade. My code with bullet compiles fine and runs fine with static or shared libraries when I compile it on it's own with g++. However, when I put that same code in a ROS package and compile it with the same shared libraries from bullet, it throws a segfault every time. So I've made very very sure (ldd on the binary) that the executable is pointing to the right libraries. And in fact, I've gone in and moded the bullet source code with some print statements and when I run my code, it prints out. So I'm sure it's pointing to the right ones.

So in one sentence, my bullet code runs fine when compiled on it's own, but when compiled in a rospackage using make (instead of just using g++ at the command line) it throws a seg fault. Same code.

So the issue(s):

So after spending a bunch of time tracing down the segfault, I found that creating btRigidObject objects was sometimes returning null pointers to their motion state. Then in my code when I tried to access these null pointers, I would get a segfault. So I went and added print statements to give me the pointers in my code and in the btRigidBody.cpp file in the construtor and the function it calls (setupRigidBody). So when I create the deafultMotionState the pointer is good. When the constructor sees it, the pointer is good all the way through setupRigidBody and out again. m_optionalMotionState is also good at the end of the constructor. However, back in my code immediately after the rigid body is made, sometimes rigidBody->getMotionState() which only gives me back the private variable m_optionalMotionState is suddenly a null pointer. Even though my print statements just printed out that it wasn't right before it returned the rigidBody.

However, the behavior is also inconsistent. As in, it does not happen every time I create a rigid body with the same code (I am using a function called createRigidBody that takes some necessary arguments and does the repetitive steps and then passes me back the rigid body). For clarity, I am checking the pointer within that function immediately after the rigid body is returned by the bullet constructor so hopefully no funny business is happening in the white space.

So the times that the the motion state pointer happens to go null, a seg fault is thrown when I try to access it.

But the plot thickens. If I immediately after the rigid body is returned, I use setMotionState(defaultMotionState) to give it back the default motion state, the code will run without segfaulting as you might expect because I never try to access a null motion state. The weird thing here is that I run many simulations in the course of this code. Each simulation creates 3 objects, does it's thing, and returns to me where one of the objects ends up. It is not always the same object that gets a null pointer to a motion state. In fact, sometimes all three get good pointers despite that the simulation is simply rerun a bunch of times and thus nothing should be different. However, if I don't do the setMotionState thing I started this paragraph with, the code 100% of the time segfaults on the same line (accessing the motion state of the third object) the first time I run the simulation. This makes 0 sense because if it can run all the way through with the hack above, sometimes the first simulation gives a good pointer for the motion state for the third object and not for other objects. And to add to it, the simulation results I get back when it runs through look very very odd. So something still seems up even if it can run.

Thoughts and confusion:

The only thing different about this folder of code and the other folder seems to be that this folder is inside of ROS and thus uses CMake and make to build instead of me just using g++ at the command line. It seems to point to the same folders. And even if I go into this folder in ROS and use g++ to point to the same libraries, it still works just fine. The code is identical besides now the 10,000 print statements everywhere to try to debug it. This makes me want to lean to blaming the compiler. I have forced cmake to use g++ to compile (or pass the compilation) and that seems to be set properly. But that still makes no difference. I've made sure that the executable is actually pointing to the right version of bullet (the same shared libraries that the executable that works [compiled with g++] points). I'm not sure if there is some optimization flag that I'm not setting exactly the same in cmake and make that I was setting with just plain g++ or if there is some other problem. But I have been tracking down this segfault and lots of things are pointing to perhaps there is a code problem somewhere even though I didn't change the code. But too many fishy things are going on.

Does anyone have any ideas, thoughts, suggestions, comments, coping mechanisms, inspiring quotes, hugs to help with this?

thanks for reading this horribly long explanation.
xexuxjy
Posts: 225
Joined: Wed Jan 07, 2009 11:43 am
Location: London

Re: btRigidBody motion state null error

Post by xexuxjy »

Which ctor are you using for RigidBody?

btRigidBody( const btRigidBodyConstructionInfo& constructionInfo);
btRigidBody( btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0));

not that it should matter really...
barragan
Posts: 3
Joined: Sun Mar 03, 2013 5:52 am

Re: btRigidBody motion state null error

Post by barragan »

I'm using the constructor with rigidBodyConstructionInfo. I was using that in both pieces of code as they are identical. So one of them still worked fine and the other sometimes returns a null pointer. The other version simply creates the constructionInfo from the input parameters so I think it will still do the same thing. But I tried it anyways just in case and got this error:

~/pr2_repo/ros_workspace/bullet_include_test/src/BasicDemo.cpp:32: undefined reference to `btRigidBody::btRigidBody(double, btMotionState*, btCollisionShape*, btVector3 const&)'

which is also very interesting because the declaration of that function is expecting a btScalar as the first argument. Not a double. And the variable I feed it is in fact a btScalar. It is also being used in a function collisionShape->calculateLocalInertia a couple of lines above which also needs a btScalar and the compiler does not complain about this. So to one function is does appear correctly to be a btScalar and to a function a couple of lines below it suddenly is no longer a btScalar but in fact a double. There is no where between the two functions where btScalar mass is changed.

Just even more to add to the puzzle.