JOODE: JOINTS

Right!

I found a bug in the joints functionality. I added an extra two test classes:-
TwoBodyHingeTest and TwoBodyBallTest,

the previous two test classes were two complicated. These tests just join a joint between two bodies and test the functionality. I have also refactored the way testing is done. The 4 joint test now extends TestingWorld, which sets up the screen and gives the tests a step() method for the main to call. Its alot cooler, but no collisionManager is present (as it is not needed for these simple tests)

I found an error in the joints which was actually a common execution pathway for both of them (so it was not the physics intergrator). In seting up the joints constraints they both build from a ball joints constraints with a method called setBall(Joint joint, Joint.Info2 info, Vector3 anchor1, Vector3 anchor2)

It is in the info object where the jacobian matrices are placed. anyhow the mistake I made when porting was to call the following method

[quote]MathUtils.dCROSSMAT_MINUS_PLUS(info.J1a.getData(), a1, s);
[/quote]
dCROSSMAT_MINUS_PLUS takes 2 Real as parameters, but J1a is a RealPointer. So I just used the data inside the jacobian RealPointer.

However, ODE is very clever in the integrator. ODE uses ONE big block of data with different pointers to the data, so in actual fact the index to the data needs to be taken into account.

So I upgraded dCROSSMAT_MINUS_PLUS to take two RealPointers and to take into account the indexes of the pointers when doing the math

then the call in the setBall became:-

MathUtils.dCROSSMAT_MINUS_PLUS(info.J1a, new RealPointer(a1), s);

Note I had to wrap a1 which was of type Real with a tiny instanciation of a RealPointer. This is fine and is all over the code, its best to make the math code as flexible as possible becuase we might never know when the 2nd parameter is stored in a clever way.

Anyway. the point of this is that the TwoBodyBallTest works for the Cholesky & the LCP intergrator! Ball joints are on the road to working! The don’t work in BallAndSocketTest, and the hinges do not work yet, but definatly we are getting somewhere now.

BTW if you get an error message saying A is not a posative definate that means the Cholesky intergrator is turned on, switch it in step_island_x1, I think I may have commited that change

nice work :slight_smile:

Oh baby … you gotta see the working BallAndSocketTest! 8)
EDIT: It only works with the LCP intergrator. The Cholesky intergrator throws a not symettric definate message and crashes (I tried reverse packing as well). So perhaps the Cholesky intergrator cannot handle joint networks …? Seems a bit too crap though.

So ball joints are fully working!

I am still working on the Hinge joint. I removed all the functionality for powering the joint.

[quote]Oh baby … you gotta see the working BallAndSocketTest! 8)
[/quote]
Yeah - that one rocks :slight_smile:

[quote]I found a bug in the joints functionality.
[/quote]
That’s nothing that could have gone wrong in the JointContact stuff, too? That could be a reason, why the Box-Box collisions are so strange…

Woo! Update … HingeJoints are now fully working. I am not quite sure why :slight_smile: I think my tests were wrong.

Again HingeTest is a peice of art to watch … maybe even better than BallAndSocketTest

SliderJoints have now been added and lightly tested, I think they are fully working.

A more complicated test of joints has been added called EngineTest, it is supposed to simulate an engines crankshaft, cams and cylinders. It seems to fail however whenever the joints form a kinimatic loop (static environment -> crankshaft … piston -> static environment). So I dunno whats up with that yet. I am pretty sure it is something ODE can normally handle.

FixedJoints implemented. Still trying to work out the kinimatic loop problem. Seems weird.

Good work ! I’m still following the JOODE project with interest.

good job :smiley:

[quote]FixedJoints implemented. Still trying to work out the kinimatic loop problem. Seems weird.
[/quote]
maybe we should do a testcase with odejava for this, so we can see if it really worked with odejava…

myeah maybe. I know I have used odejava in the past with some very complicated kinimatic loops, but these were loops that were never fixed to the static landscape. I am gonna try doing some pure body loops and see what happens.

Oh yeah and I must say that it is a weirder problem than I first though. The engine does not blow up on the first step, rather about the 8th step down the line. I have found a load of NaN from the results of FastLDLT factorise. I actually re-ported the code just in case it was a porting error but it still did the same thing so :-.

OK. Well just a plain Kinimtic loops breaks the system even when not tied to only bodies.

The problem is a divide by zero creeps in from the recipricol method:-
dRecip
in MathUtils.

This method is called in FastLDLT.dFactorLDLT() called in LCPDriver. This apparently is another sneaky alternative to solving the constraint equations when only unbounded constrains are present. If bounded constrainst are present then the driver tries the LCP algorithm. I have tried removing the FastLDLT.dFactorLDLT functionality (and just relying on the LCP but this fails as well).

The test class KinimaticLoop (sorry I need to rename that to KinematicLoop) demonstrates the problem. What is interesting though is that I can alter dRecip to return a very large Float instead of infinity when 0 is passed in, and this actually stops the engine blowing up, and actually makes the KinimaticLoop situation work!! However it does not fix EngineTest and is so hacky I do not think it would be the way to go anyway.

I think your right arne. I should have a play with ODE and see how it manages in these cases… I might have to stop working again soon though, my workload is mounting again :frowning: presentation a week Tue :frowning: :frowning:

OK. I found this great bit of info for BlueSky:-
http://ode.org/cgi-bin/wiki.pl?ConstrainingObjectTo2D

(its about keeping objects in 2D with joints, and a little about constraining their rotation)

There is more cool info on ODE.org that never used to be there about creating custom joints. That above link though is right up your alley :slight_smile:

Damn… I have lectures early 2morrow and I am not in bed yet…

Well I have jsut had a little time this weekend so I have tried to solve the kinimatic loop problem.

It was a weird problem becuase the sys would step fine a few times before breaking from a divide by zero. I traced the values of the offending number in the working steps before the divide by zero occured and found that they were like 0.00006 and counted to zero. As such I think it was just a numerical rounding error. I have created a dRecipSafe method that peturbs the value by a tiny guassian if it is zero. This does get KinimaticLoopTest working. To test another kinimatic loop I created a cube where all the edges are slider joints and gave it a force. This seems to work as expected expanding the cube size but keeping it in shape. EngineTest explodes when run, but its a bit of a weird test anyway so only time will tell if we can get away with this crude fix in practice.

Anyway I am quite happy now. JOODE can probably be used in some things now…

So you would go the DEEP way ? :wink:
I’ll study this algorithm if I have time.

Yeah it was the DEEP algorithm I was trying to explain earlier. I have a few mods though for it …