Crash inside Bepu

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
Danthekilla
Posts: 136
Joined: Sun Jan 17, 2010 11:35 am

Crash inside Bepu

Post by Danthekilla »

Norbo I cannot figure out why this crash is happing.

Ok so I create 2 bodys
Then link them using a revolute joint as seen here

Code: Select all

            Bodys.Add(new Box(new Vector3(0, 2, 0), 2f, 4f, 2f, 100));
            //Bodys[0].mass = 0;
            Bodys[0].dynamicFriction = 1.0f;
            Bodys[0].staticFriction = 1.0f;
            InitialPartStats.Add(new EntityPartStat(new Vector3(0, 0, 0), Quaternion.Identity));

            Bodys.Add(new Box(new Vector3(0, 2, 1.2f), 0.5f, 3f, 0.1f, 15));
            //Bodys[1].mass = 0;
            Bodys[1].dynamicFriction = 1.0f;
            Bodys[1].staticFriction = 1.0f;
            InitialPartStats.Add(new EntityPartStat(new Vector3(0, 0, 1.2f), Quaternion.Identity));

            //Connect the saw to the piston with a second axis joint.
            //Revolute joints can be used to make axis joints (as it is here), but you can also use them to make hinges.
            //Make the blade spin.
            RevoluteJoint axisJoint = new RevoluteJoint(Bodys[0], Bodys[1], (Bodys[0].centerPosition + Bodys[1].centerPosition) / 2, Vector3.Forward);
            axisJoint.motor.isActive = true;
            axisJoint.motor.settings.velocityMotor.goalVelocity = 20;
            axisJoint.motor.settings.maximumForce = 200;
            Constrants.Add(axisJoint);
Now when the editor changes from editing mode to running mode it has to re-build some items
When this happens it goes though each object and kills there physics using this code here.

Code: Select all

        public void KillPhysics()
        {
            for (int i = 0; i < Bodys.Count; i++)
            {
                if (Bodys[i] != null)
                    if (space.entities.Contains(Bodys[i]))
                        space.remove(Bodys[i]);
            }
            for (int i = 0; i < Constrants.Count; i++)
                if (Constrants[i] != null)
                    if (space.solverUpdateables.Contains(Constrants[i]))
                        space.remove(Constrants[i]);
        }
Now when the code hits "space.remove(Constrants);" it crashes.
but only if I make both bodys dynamic if I comment out "//Bodys[0].mass = 0;" then it removes it fine...

Any idea what I am doing wrong? Or have a found some kind of super rare bug?
Danthekilla
Posts: 136
Joined: Sun Jan 17, 2010 11:35 am

Re: Crash inside Bepu

Post by Danthekilla »

Also how should i go about deactivating a joint?
There is no Joint.Break() function that i can see.

I am currently trying this? Would anything like this work?

Code: Select all

            if (Constrants[0] != null)
                if (((RevoluteJoint)Constrants[0]).ballSocketJoint.error.Length() > 1)
                    (Constrants[0]).space.remove(Constrants[0]);
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Crash inside Bepu

Post by Norbo »

For joint breaking, you can either remove it from the space or use the constraint's isActive property. When isActive is set to false, the constraint will still exist in the space, but will do no computations.

Testing the error length (squared) or the totalImpulse (squared) against some threshold will work for determining when to break. The totalImpulse is just a measure of the force the constraint is applying.

For the crash, does it happen only when both involved entities are kinematic or does it also happen when at least one is dynamic? Constraints aren't designed to work with two kinematic connections since both entities would have infinite inertia and the constraint could do nothing. It would be strange to crash on a removal from the space though, I'll take a closer look in a minute.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Crash inside Bepu

Post by Norbo »

I think I reproduced it. It's a null reference exception right? It's caused when a constraint is removed from the space when the entities involved in that constraint do not belong to that space. If you remove constraints first and then entities, the crash should disappear. I'll try to fix it or at least put a more verbose description of why it fails in an exception.

In further investigation, I found a small bug where SolverGroups (like the RevoluteJoint) did not properly manage an internal list of involved entities if they were kinematic. It has been fixed for the next version, but it's not obvious that it could have caused any visible bugs anyway.

By the way, a faster way of checking if a constraint belongs to a space is to check its space property. If it matches, you can safely remove the constraint from the space.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Crash inside Bepu

Post by Norbo »

The fix has been implemented for the next version- the simulation island system is a little smarter about what it tries to split when things are removed now.
Danthekilla
Posts: 136
Joined: Sun Jan 17, 2010 11:35 am

Re: Crash inside Bepu

Post by Danthekilla »

Yer it was a null referance exeption.

And you were right swapping the removes around got rid of the crash.
Which is good to see :)

2 other questions however.

What is the best way to get the speed at which an object is being spun by a motor at (there is no motor.currentspeed or anything like that that is public that i can see)

and also we seem to get crashes when ever we update the simulator with a timestep of 0 (we need to do this in the editor to update positions etc...)
0.0000000001 works but then we eventually get some slight drift.
i do this using

space.simulationSettings.timeStep.timeScale = 0.00000000001f; //0.0f;

it throws this exeption

An unhandled exception of type 'System.ArithmeticException' occurred in BEPUphysics.dll

Additional information: Some internal multithreaded arithmetic has encountered an invalid state. Check for invalid entity momentums, velocities, and positions; propagating NaN's will generally trigger this exception in the getExtremePoint function.

Its not too much of an issue but i was wondering if you had a work around? (also its only when i have a revolute joint in the simulator, reguler bodys work fine )

Thanks for the exellent help Norbo :)
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Crash inside Bepu

Post by Norbo »

What is the best way to get the speed at which an object is being spun by a motor at (there is no motor.currentspeed or anything like that that is public that i can see)
One way is to take the dot product of the angular velocity of each entity against the revolute motor's basis's primary axis. This is the 'free swinging' axis in a revolute joint, and is powered by the revolute motor. The resultant products represent the velocity of each entity's rotation around the axis.

Code: Select all

float velocityA = Vector3.Dot(revoluteJoint.motor.connectionA.internalAngularVelocity, revoluteJoint.motor.basis.primaryAxis);
float velocityB = Vector3.Dot(revoluteJoint.motor.connectionB.internalAngularVelocity, revoluteJoint.motor.basis.primaryAxis);
float velocityDifference = velocityA - velocityB;
I've been thinking about how to best expose the jacobian information in general for joints. The 'jacobians' are basically the axes that the constraint is working on, and in the above, the primaryAxis is it. Having them available on constraints is useful for robotic simulations in some situations and can be used to calculate the velocity 'error' of a constraint as in the above. Right now, while it's easy enough for the revolute motor, other constraint types are trickier. If I provide a jacobian interface it would probably also include a velocity error calculating method.
and also we seem to get crashes when ever we update the simulator with a timestep of 0 (we need to do this in the editor to update positions etc...)
Unfortunately, many parts of the engine rely the inverse timestep which becomes nasty when the timestep is zero. Most likely the culprit in your case is the revolute joint's position correction, which requires a division by dt to simulate its rigid spring behavior. I believe active deep collisions will also cause a problem.

I assume the reason that you need to call update is to flush the write buffer/update the read buffer due to using buffered properties. If this is the case, there is one slightly annoying workaround: use the internal versions of the properties instead (like internalCenterPosition). They are unbuffered and directly change entity property values without waiting on the update. It will be safe because the engine will not be updating anyway.

I'll look into providing some buffer management methods for the next version so that they can be flipped/flushed independently of the update method if needed. I'd also like to address the common issues with buffered properties vs non-buffered properties. In the vast majority of cases, using the non-buffered properties is perfectly safe (except when asynchronously updating). However, since the non-buffered properties have a prefix of 'internal' it is more natural to use the buffered properties. Usually this works out okay, but it is a source of some pain for people trying to figure out why the value of centerPosition won't change when they set it.

I may end up pushing the buffered/interpolated states into a slightly more hidden, condensed single motion state property. People who need them will know to use them, and the rest of the people will get what they expect from setting centerPosition. The remaining concern then is how to deal with a very sneaky breaking change that makes formerly buffered properties unbuffered.
Danthekilla
Posts: 136
Joined: Sun Jan 17, 2010 11:35 am

Re: Crash inside Bepu

Post by Danthekilla »

Yer I think that having the buffered propertys with a prefix of buffered would be better than the reguler ones having internal on them as a prefix...

I cannot remember why our editor require bepu to be updated... I know there was a reason (I might look at it later)
There is probably somewhere I am using the buffered states (I probably forgot)
But in general we use the internal ones for everything.

A little off topic but I am trying to get a new object in our editor that changes the direction of gravity to the direction it is aiming at when touched...
How should I go about lerping the camera to match the new gravity? If you have any ideas let me know :)

Anyways thanks for all the help.
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Crash inside Bepu

Post by Norbo »

How should I go about lerping the camera to match the new gravity?
You could use the Toolbox.getQuaternionBetweenNormalizedVectors function between the camera's current up vector and the negative direction of gravity (assuming you want your camera's up to align with the opposite of gravity). You could then slerp between the unmodified orientation and the modified orientation (rotated by the computed quaternion).

Another way would be to use dot/cross products to do something similar.
Post Reply