Pure Java Port of ODE - planning/feasibility

How has the project creation gone? It looks like you’re well over the 3 votes needed. What is a URL where we’ll be able to find the JOODE source tree? What requirements woudl there be to be able to contribute?

I think Jeff must be AWOL or something. He has not replied to my initial emails, nor reacted to me posting into the forum directly. There is a minimum period of 5 days of voting anyhow before we are given status.
The project home will be
joode.dev.java.net

If you want to contribute porting code, then you can just commit to the project. If you want to do some funky cutting edge stuff then wait until we get the code running.

I really don’t get this project application proccess. I setup a project on java.net a while ago and it said waiting for moderation. I could still browse it and do things. Since then it has been deleted without any warning. I have just re-set it up again.
I have also commited all the source I have been working on this time so the administrators won’t think it is empty. The voting process seems to be going nowhere as well.

sourceforge.net? :stuck_out_tongue:

[quote]sourceforge.net? Tongue
[/quote]
I think we should give it a bit longer. But I don’ want to wait another whole week, I want help!

I have managed a fair bit of code so far. I think I have coded the stepIsland method which is a beastie, but I have not testing framework in place yet so I don’t know if any code actually works. I think the next method is the final big one … the LCP algorithm and then I think the prototype system will essentially be in place. I have coded the model data structures (Mass, Body, Space, Geom, Joint, etc.) and the simplest forms of each (SimpleSpace, Sphere, actually no joints). I have then tried to code the actualy workings of ODE, I think I have the collision system translated, but the dynamics are harder. I have started on the outside and workied inwards, doing StepIsland and now onto LCP. The LCP algorithm quite nicely has some nice test methods so maybe I will be able to test that code.

Testing is gonna be a real issue I feel. I was thinking maybe a good idea would be to use ODE class in ODEJava to test some of the functionality. But ODEJava only exposes the highest level of ODE functionality, it won’t probably won’t be helpful in fixing bugs. You can use it to be sure something works. But actually fixing it will still be hard.

I am away this weekend so if the project appears there might be a little delay before everyone gets their rights.

The only thing that is left to establish is how closely are you going to follow ODE…What I mean by that questions is what are you going to do when ODE adds a new feature (like convex hull collision), are you going to port their code to java?

Or are you going to get what ODE has now and just work from there regardless of what ODE does?

DP

Another Week went by - and still nothing! >:( Maybe we should really switch to sourceforge !

@t_larkworthy: have you got the PM I send you?

I’d say, it depends on how easy it is to port the new feature. But maybe it would be wise to keep in step with ODE, so ODEJava code using ODE can easily be switched to JOODE.

Arne

OK everyone. I think things are beginning to happen on the proejct formation front. I have had some emails and things, so hopefully we shall be rolling soon.
Yes Arne I got your PM. I have just been away for the weekend.

[quote]The only thing that is left to establish is how closely are you going to follow ODE…What I mean by that questions is what are you going to do when ODE adds a new feature (like convex hull collision), are you going to port their code to java?
[/quote]
Myeah, I think it would not be hard to add new features as they come out for ODE, but only bother if they really add something. I think we should be trying to develop our own solutions to deficits in ODE. I really want a nice collision system for example, and I don’t want to wait for ODE to develop it.

OK I have had some requests from prospective developers for a copy of the sources I have done so far.
here is a link to them:-
http://homepages.inf.ed.ac.uk/s0570397/joode-src.tar.gz
Please realise though that these are not stable in anyway yet and it would probably not be a good idea to try and develop from them.

This has been a long time trying to get the dev.java.net account set up. I’ve set up several myself, and while it does take a few days, this is a particularly long wait.

Browing to joode.dev.java.net, it looks like a project has been created for you, but you might still need to log in and set it up before others can access it.

There are help forums for administering dev.java.net, and I’ve found that the folks who read these boards are often administrators who can pull strings behind the scenes. Try posting to the boards below and see if this helps get the JOODE site set up quickly:

https://java-net.dev.java.net/servlets/ProjectForumView

Mark McKay

Just had a quick look at the source archive you posted. While I’ve not had time to look though it in detail, I did notice that the root package was joode. Could I suggest it be changed to net.java.dev.joode, or something similar to keep the package naming convention?

Mark McKay

[quote] Could I suggest it be changed to net.java.dev.joode
[/quote]
yes. It shall be done

Nice work - I wasn’t able to look at all the code yet - or better: to understand the code.

I looked at the Matrix representations in joode.util and I really like how it’s done - Vector, Matrix and Quat all extending Real, but to make the design better and the code more readable I’d suggest to make Real to save a 2-dimensional array and not a simple array (I believe they had to do this, because C only supports one-dimensional Arrays - correct me if I’m wrong).

A better structure would be even:

                     Real   <--- Quaternion
                       A
                        |
                    Matrix
                    A     A   
                  /            \
               /                  \

SymmetricMatrix Vector
A A A A
| | | |
Matrix3 Matrix4 Vector3 Vector4

(The A’s are arrowheads)

The function in MathUtil could then be moved into the according class. We want be able to have an extra class for all diferent kinds of matrices, so Matrix represents a nxm matrix. In Matrix there should be a method to multiply two matrices, because this might not always work - we should in the cases, when this doesn’t work throw an exception. A method canMultiply would then be also nice.

Optimisations of linear equatation-system can get solved with the Simplex algorithm, where you specify the linear equatation system inside a matrix. Because we might have to do such calculations - we could also add such a method to our Matrix class.
We could then hehe :wink: linear optimise a translation matrix :smiley: - I don’t know what kind of crude hack would require this, but it’s a funny thought. ;D

Arne

Yeah. It would be nice to extend the matrix into 2D, but I did it this way becuase all of the math functions in ODE do really clever/hacky stuff using the faact they are stored in one dimention. I don’t understand half the math functions but if they are stored in joode the same way I do not need to, I can just translate the way ODE skipps around the indexes in joode as well.

I have hit a bit of a brick way trying to port the LCP algorithm but I have a new stratergy. For the functions that do loads with pointers I have introduced the PointerToReal class. This stores the underlying Real and an index. When ODE code increments a pointer I can simply add to the index of the joode version. When ODE assigns one pointer to another I can then just copy the array reference across the pointers and set the index. I think this is the easiest way. The LCP algorithm is a monster to translate though, so it may take me a while.

ok - but we could have a function like get(int x, int y) that automatically translates into the correct position in the linear array. And then we could add a function get(int n) that returns the value of the n’th position of the data array. Then we won’t have to have the data array to be public and then we could still change it afterwards to a 2*2 matrix, if we like.

To add stuff to pointers makes only sense, if you’re dealing with arrays - and there we’ve got the indices, so it should be no problem, we could simply increase the index (a pointer would then be a simple int). I don’t understand your PointerToReal class, simply use my suggested get(int n).

Arne

mmh I believe I know now why they use all those skip variables… they don’t specify the width in Real, so they always have to specify it in the function call. I believe now they misuse this, to save loads of matrices in their Real objects. (That’s why there are starting points… but hmm sometimes such is missing … maybe I’m wrong) Even if it gains a bit of performance we should not code JOODE like that, because

  1. you can’t read it
  2. you can’t find errors that easily anymore.
  3. you don’t know what the function does and how it does that.

Ok I know that’ll be much harder than just porting it, but this design is so hacky and crude - we really should try to make it into nice code starting with joode.util, so we’ll know how to call the functions. It’ll make further porting and improving of the code easier, so it’ll be worth the effort.

Functions defined in MathUtil (I only printed those that weren’t more or less represented by other functions):

dDotpq(Real a,Real b,int s1, int s2, int p,int q); // -> Real ?
dCROSSpqr(Real a, Operator op,Real b,Real c, int p, int q, int r); // -> Real ?
dCROSSMAT(Real A,Real a,int skip,Operator plus,Operator minus); -> Real ?
dDISTANCE (Real a, Real b); // this is easy -> Vector
dMULTIPLYOP0_331(Real A,Operator op,Real B,Real C, int as, int bs, int cs); // what kind of matrix multiplication is this??
dNormalize4 (Real a); // -> Vector, Quat
dMultiply0 (dReal *A, const dReal *B, const dReal *C, int p, int q, int r); // why are there 3 different types of multiply?
dFactorCholesky (dReal A, int n); // what is FactorCholesky???
dSolveCholesky (const dReal *L, dReal *b, int n);
dInvertPDMatrix (const dReal *A, dReal *Ainv, int n);
dPAD(int a); // what's this?
dIsPositiveDefinite (Real A, int n);
dVectorScale (dReal *a, const dReal *d, int n) // -> Vector
dSolveLDLT (const dReal *L, const dReal *d, dReal *b, int n, int nskip) // what's this?
dLDLTAddTL (dReal *L, dReal *d, const dReal *a, int n, int nskip)
dLDLTRemove (dReal **A, const int *p, dReal *L, dReal *d, int n1, int n2, int r, int nskip)
dRemoveRowCol (dReal *A, int n, int nskip, int r)  // -> Real
dRFromAxisAndAngle (dMatrix3 R, dReal ax, dReal ay, dReal az, dReal angle) // -> Matrix3, Matrix4
dRFromEulerAngles (dMatrix3 R, dReal phi, dReal theta, dReal psi) // -> Matrix3, Matrix4
dRFrom2Axes (dMatrix3 R, dReal ax, dReal ay, dReal az, dReal bx, dReal by, dReal bz) // -> Matrix3, Matrix4
dRFromZAxis (dMatrix3 R, dReal ax, dReal ay, dReal az) -> Matrix3,Matrix4
dQSetIdentity (dQuaternion q) // -> Quaternion
dQFromAxisAndAngle (dQuaternion q, dReal ax, dReal ay, dReal az, dReal angle) // -> Quaternion
dRfromQ (Matrix3 R, Quaternion q) // -> Matrix3
dQfromR (dQuaternion q, const dMatrix3 R) // -> Quaternion
dDQfromW (Real dq, Vector3 w, Quaternion q) // -> Quaternion
Multiply2_p8r (Real A, Real B, Real C, int p, int r, int Askip, int as, int bs, int cs) // -> Matrix ? -> Real?

I wrote behind most of these methods, where it should belong to (i.e. -> Matrix3). Sometimes I didn’t really know what the function does, so I’ve put a comment (i.e. what’s this?). This way we should be able to sort all these functions into their according classes pretty easily. The porting shouldn’t go harder then, because you’ll only have to make e.g. dRfromQ(Matrix3 R, Quaternion q) to Matrix3.set(Quaternion q).

oh sorry

[quote]dMULTIPLYOP0_331(Real A,Operator op,Real B,Real C, int as, int bs, int cs); // what kind of matrix multiplication is this??
[/quote]
is something I added. Noramlly in ODE there is the function
dMULTIPLYOP0_331((Real A,Operator op,Real B,Real C)

However quite often code in ODE will call this function like
dMULTIPLYOP0_331(a +3, …) meaning they increment the pointer a by 3 indexes before passing it to the function. This cannot be done in java where our dReals are arrays in a Real object. So in joode I have have coded it so that you pass the array in, and also a starting index (so the last 3 ints are the indexes to start indexing the arrays contained in the first 3 Real objects).

This seemed like the easist way to do it when I first started coding. I am beginning to think that this way of changing a pointer into an array and index is confusing when there are alot of pointers around. I am thinking that pointers should be encapsulated as a datatype of their own for joode. It would make converting some code alot easier.

ok, but that actually doesn’t answer my question :wink:
When I think about matrix multiplication I think, that’s Matrix A = B*C (if the function writes the result into A). So where comes there an operator in and what sense does it make to start multiplying at i.e. m22 in the matrix? Or is the Type Real really used as something like a list of Matrices, Vectors… ?

The operator parameter allows the users to say instead of multiply the result of B and C and putting into A (by passing in * as the operator) they can also say multiply B and C and add it to the existing result in A (by putting += as the operator). Its fairly horrific. I have had to code alternative methods for each operator usage.
As for skipping stuff, yeah they do that alot. For some reason eclipse has just bust on me so I cant find where abouts they do this. But yeah, they do all kinds of weird stuff with the pointers. I know the LCP algorithm holds various of its intermediate results in massive dReal arrays. Also in the LCP algorith it uses the notion of Jacobian matrices which are 3x6 matrices, and I have no idea how they work.