Collision question for ODE bindings

Hey everyone,

I’ve been using the JavaODE bindings to write some programs and multi-body simulations and so far everything is going quite well. However I’m at the point where I want to do some custom responses to collision events (like sound effects, etc).

It’s my understanding the JavaODE doesn’t have the higher level interface to the collision objects complete? Is that right? If there are low level ODE objects available, would it make sense for me to try and write something to contribute?

Does Fuze3D provide any kind of collision information? I couldn’t figure it out from the website.

Thanks alot.

Matt

You are right. Higher Level API depends to Lower Level API. Lower Level API is one to one with Ode itself. So hardcore coder can use Ode’s own ideas and documentations when extending Higher Level API.

If you are up to edit odejava.i (swig definition file) and compiling odejava library yourself then this would be great. Ode itself contains all the information that you described here. The problem here is that Lower Level API (Java side) is not complete when it comes e.g. to contact points structures. Lower Level API is stable and works very well, but almost all it’s “TODO” functions relate somehow to contact information that Ode generates on collisions.

I just inspected odejava.i file and here’s part of it:

/* joint force feedback information /
// TODO
//typedef struct dJointFeedback {
// dVector3 f1; /
force applied to body 1 /
// dVector3 t1; /
torque applied to body 1 /
// dVector3 f2; /
force applied to body 2 /
// dVector3 t2; /
torque applied to body 2 */
//} dJointFeedback;

/* contact info set by collision functions */
// TODO
/*typedef struct dContactGeom {
dVector3 pos;
dVector3 normal;
dReal depth;
dGeomID g1,g2;
} dContactGeom;
/
/
contact info used by contact joint */
// TODO
/*typedef struct dContact {
dSurfaceParameters surface;
dContactGeom geom;
dVector3 fdir1;
} dContact;
*/

So, these are on “TODO”, I have commented these out, this was due to the fact that swig couldn’t convert JNI (Java classes) out from these structs without compile errors. These should not be too hard to fix though…

After these are added to Odejava I feel the C side callback also needs some work in order to pass the information required on the Java side, this should be also quite simple.

Other option is to convert callback function into Java completely, this could take some time, however I know this was done e.g. in odeforjava project. Also this might have some performance issues (do not know how heavy though). Odeforjava project is discontinued project though. Perhaps we should ask the Odeforjava’s author some help for these, the project’s author is on Odejava project members list. (note Odejava != odeforjava).

I do not know, hope the author writes his answer here. I feel fuze3d’s API is somewhat ahead when it comes to Odejava, but fuze3d depends to Openmind scenegraph and Odejava is more independent. Odejava can be easily plugged into any 3d rendered / scenegraph libraries. This is a very rough distinction for Fuze3d vs. Odejava. I haven’t checked Fuze3d too much yet, seems great project though!

Best Regards, Jani!

Great, thanks for the information Jani, that definately clears up some of my confusion about the collision interface.

I’m definately interested in helping out, however my C is a little rusty, and I’m not familiar with SWIG so I won’t be any immediate help in those areas. If you or someone else could manage to get the low level collision joint structures to compile then I could write a high level wrapper for that whole system.

However, if you don’t have time or don’t feel like doing the low level SWIG work then I could take a look into that as well and see what I can do. Certainly the callback mechanism seems to be the sticking point in all that, hopefully one of the projects you mentioned will have a solution on how to implement that with JNI.

For the moment we have a rudimentary collision system working in Java which simply checks all objects in our simulation to see if their velocity has changed in magnitude over a certain threshold value, which we then interpret as a collision. We are only triggering sound effects for those collisions at the moment so that’s fine, but we’ll soon want specific information on the nature of the collision, so that’s when we’ll start working on the interface.

So, let me know how you’d like to proceed, and whether you feel like doing the SWIG part of things or not and we’ll get started.

Thanks for your help,

Matt

In short, here’s one solution, leave the original nearCallback still to odejava.cpp, but change it in the following way:

void nearCallback (void *data, dGeomID o1, dGeomID o2) {
dBodyID b1 = dGeomGetBody(o1);
dBodyID b2 = dGeomGetBody(o2);

// Optional: optimization: exit without doing anything if the two bodies are connected by a joint
if (b1 && b2 && dAreConnectedExcluding (b1,b2,dJointTypeContact)) return;

// Optional: do some other (future) optimizations here if you wish
// …

// Pass execution to Java nearcallback method
//
// BEGIN: This needs to be resolved…
//
JNIEnv *env;
(*jvm)->JavaNearCallbackClass(int o1, int o2);
//
// END: This needs to be resolved…
//
}

So we need to call Odejava class’s method out from the native library. This should not be too complicated, I know JNI supports calling Java methods out from C libraries but I have not done this before.

Are you willing to check JNI documents + examples and see how to do this? Basically if you can call Java method with two parameters (int geomId, int geomId) then the rest should be pretty easy. This solution allows the best flexibility as also nearCallback related tasks can be defined in Java.

After this you get all the collision related data you want in Java and you can use it as you wish, e.g. for generating sounds depending on how hard one geom hits another…

In that case you might be able to forget nearCallback completely and call only dCollide function from Java for each probable collision that occurs, it depends how rudimentary your library is :). But for efficiency reasons you might want to use ODE’s highly optimized collision library.

If you have some extra time, check how one can call Java class method throgh JNI. The rest should be quite easy to do, they might even be ready already on Odejava.

I have some free time next weekend, if you come up with anything, mail your results directly to me.

Cheers, Jani!

Solution is coming… I hope :slight_smile:

Forget the previous post, I got the rest of Odejava.i enabled, now there’s dJointFeedback, dContactGeom and dContact classes on the Low Level Java API. These were the last structures that were commented out because Swig couldn’t give proper JNI out of them. Now I got them compiled, but they need to be tested.

Also, I got some help with creating the callback on the Java side, this is also going forward. Have to see how it goes. Current implementation still handles nearCallbacks under native library, but the real collisions will be passed to Java side. This is more effective and also simpler to accomplish.

I’ll write here when I’ve committed new Odejava.

Hi Jani,

I am actively working with odejava to build a robot simulator. In order to simulate sensor we need more control on collision detection.

Can you estimate when these features will be on CVS ?

If you have a preliminary patch, I would be very glad to get it so I can start testing it and possibly give you some feedback.

Thanks,
Paolo

Today evening (again). It has been ready for some days but the code is in such state that I need to edit it before committing it to the CVS. I got few hours yesterday and now it’s almost complete for public usage.

This contains quite a lot changes. I try to commit it to the CVS today evening in any case, that’s in 14 hours from writing this email.

This addition allows many interesting collision related tasks to be controlled on the Java side, e.g. sound effects or set different friction or bounciness values per each object1 --> object2 collisions.

The data which you can control for each collisions is:

Contact
-Vector3f fdir1
-ContactGeom (see lower)
-SurfaceParameters (see lower)

ContactGeom
-Vector3f pos
-Vector3f normal
-float depth
-dGeomID g1,g2

SurfaceParameters
-mode
-mu
-mu2
-bounce
-bounceVel
-softErp
-softCfm
-motion1, motion2
-slip1, slip2

Good sides is that this even seems to work very fast with complex scenarios. Overhead is <1% based on initial tests with CarTerrainExample containing 200 objects.

Fantastic! I’m looking forward to testing it for triggering game events without having to perform additional collision checks in the game code. :slight_smile:

Odejava 0.2.2 is now on the CVS. The demos now access collision events and I made some minor examples on how to use new features, they should be pretty straightforward (I hope).

TriMeshExample e.g. makes. one sphere act like teflon coated (0 friction) superball (very bouncy), it also prints some stats (position, normal, depth) every time sphere1 collides with some other geom.

CarExample and CarTerrainExample are quite same, again if chassis is hit to any object, statistics are printed to system out…

Lot’s of nice things should be possible to do with these, e.g. creating sound effects or particle effects based on collisions. Hope someone makes a demo soon :slight_smile:

Higher Level API has changed, well it was bound to, what can I say.

Cheers, Jani!

Hey Jani,

We succesfully switched our previous cheesed out collision detection algorithm over to your new ODE native callback stuff, it’s working great. We are having a few performance concerns, but we haven’t really figured out whether that’s us or the new collision stuff.

In any case, it’s great that you’ve managed to get all this stuff in there, we really have a lot to work with now.

I’ll keep posting as we make more progress to keep you updated.

Matt

[quote]Hey Jani,
We succesfully switched our previous cheesed out collision detection algorithm over to your new ODE native callback stuff, it’s working great. We are having a few performance concerns, but we haven’t really figured out whether that’s us or the new collision stuff.
[/quote]
Couple days ago I tested CarTerrainExample with 200 objects constantly colliding to the ground or each other. The overhead for using JavaCollision instead of original native version was very small, less than a percent. This is identical to current CarTerrainExample, except with more objects and I was using Low Level API.

However, I changed implementation yesterday and made Higher Level API for the Collision side (org.odejava.collision.*). After this change I have not benchmarked it. There should not be any bottlenecks but if there is, they should be quite easy to fix as the code today is same as couple days ago, just wrapped few Java classes more, nothing special.

Just make sure your loop iterating the contacts per each step is as efficient as possible, e.g. do not create any objects unless absolutely neccessary (reuse them if possible), this can affect performance a lot. In here I refer to excessive usage of Java’s “new” sentence.

Also, there’s lots of optimizing that could be done, e.g. using Java’s direct buffers, but I’m not planning to make these (at least not for a while) as Low Level tests were already fast.

Jani

We had a stack of things that were in constant contact with each other (all piled up) and so when we iterate the contacts we get a contact per object per step basically. So, this is a fair number of contacts, but not enough to slow the simulation down really. The problem was that every few hundred frames (couple of seconds) or so the whole thing would just pause, looking very much like a garbage collection type of pause.

So, we optimized our loop on the java side as much as we could, no new object references and all that, but none of it mattered. Finally we narrowed it down to the contact.setCptr(addr) call. We were making one of those per collision and the call wasn’t slow in execution, but it was leaving behind some kind of garbage that eventually choked up the VM and caused a collect.

I read through the source and the object creation seems very minimal, could there be something going on in the JNI callback mechanism causing this kind of behaviour that I can’t see?

Ok, I know the cause, it’s SWIG wrapper objects that are constantly created. I wasn’t using them couple days ago but the design is now a lot more readable. This problem can be easily solved but it needs some work to odejava.cpp (recompilation required).

Swig does wonderfull work creating Low Level API, but there might be places where hand made optimization is required.

Simple solution would be to read every contact information value in a single JNI call (~20 floats + 1 int), then let user to do the updates and finally, if user has changed any value, flush Java values back to ODE with single JNI call. This will take care of this problem, as no object creation is required.

I almost made that method but then I decided to postpone
optimization questions as it already seemed to work quite fast. If it’s really important I can add two more JNI methods, it’s not too big a task, although I’d like to think this a bit more starting to work as this feels kind of a “intermediate” solution.

Perhaps the best solution would be to use Direct Buffers.

Let me know what you think, Jani!

I just added DirectBuffer support for collision related data. It should remove swig wrapper classes overhead and possible gc issues as now all data is handled through buffers (without object creation or excessive JNIs). I’m committing the changes tomorrow day.

Jani

Odejava 0.2.3 now uses DirectBuffers for collision data handling.

Previous version was thrashing memory a lot because of SWIG proxy classes were used for accessing contact data on a tight loop. This was an meaningful optimization as for complex simulations the difference on speed might be over 50%.

Summary, collision data read/write should finally be as it should. Very fast and it does not need any “new” clauses or any JNI as DirectBuffers are used.

Cheers, Jani!

Great Jani, I’ll update and try it out, I’ll post here when I get some results.

Matt

I converted over to the new interface and it works great, way faster than before and I haven’t made any efforts to optimize my routines, I’m still doing lots of unnecessary object creation on my side.

So, great work, it’s great to be able to handle all the collisions properly without having to worry about the uderlying layer making a bunch of objects.

So, I think I’ve got a bunch of things I want to write to extend the higher level API, so I’ll submit a patch against your source once I make some progress on that.

Great work, thanks.

Matt