[ODE] ODE joint internals
Matthew D. Hancher
mdh at email.arc.nasa.gov
Thu Mar 18 11:03:29 MST 2004
Hi all,
I've been using ODE for a little while now and I'm finally taking the
plunge and diving on into the ODE source. I have a few questions, as
a neophyte to this codebase. First a little background though, in
case anyone has any high-level advice about what I'm trying to do.
We use ODE to simulate modular robots. In other words, we have a
collection of simple modules, each with as few as one or even zero
joints, and we build up more sophisticated structures by connecting
them together. The connections are rigid, and when we've been
simulating non-reconfigurable modular robots it's been easy to merge
the appropriate parts of each module into a single Body at each
connection point to avoid a proliferation of FixedJoints. (The
solution using FixedJoints is, of course, obscenely slow for complex
structures.)
The next step is to rework things to support reconfigurable modular
robots. This means that I need to be able to make and break these
rigid connections during a simulation run without confusing the other
joints that are connected to the Bodys in question. And so
I arrive at the following subproblem:
** I need to be able to switch out one of the Bodys connected to a
Joint while leaving the other joint parameters (such as anchor
and axis positions, relative rotations, etc.) unchanged as viewed
in global coordinates, even though the new Body's position and
orientation may be different. **
It looks like there's no way to do this using the public API right
now; for instance, attempting to reset a Hinge anchor re-zeroes the
joint angle, which is no good. So the goal is to rework dJointAttach
so that it does the appropriate math to preserve these properties when
re-attaching a joint, or something along those lines.
Every time I start trying to do this it gets very messy, so I'm taking
a step back to get a better feel for the overal design of the joint
system. I've been reading the joint code for a while now, trying
to get inside the authors' heads, and I have a few questions.
1. Why use dJOINT_REVERSE, as opposed to allowing either body to be
zero? It seems like dJOINT_REVERSE winds up cluttering bits of
code that don't care at all whether the joint is static, and the
cost of testing both bodies where you already test one of them
seems pretty low. Is there something I'm missing that would get
really ugly if you did this?
2. Why not have a single Body, not included in the World's body list,
that represents the static world internally? It's body transform
could aways be the identity, which would let you clean up several
bits of code. Testing against this pointer would be not much
harder than testing against the null pointer, in the places where
you really need special behavior. (This could also give you the
ability to enumerate the static joints in the world for free, if
you wanted that, etc.)
3. Given that this is a C++ library internally, why bulid your own
vtables? The comment says it's because you sometimes need to
allocate joints yourslef, but isn't that what placement new is
for? It seems like letting C++ take care of this would make it
much cleaner to add new joint-type-specific functionality, like
adjusting joint parameters when reattaching joints as discussed
above.
Since I'm going to be going through the joint code anyway, I've been
considering making these changes (locally, at least) and I was curious
if anyone could think of obvious reasons why they are bad ideas. I'm
sure you've talked some or all these issuse to death at one point or
another in the history of ODE, but I'm curious how you feel about
some of the design decisions now that you've had a chance to play
with the code for a while.
Thanks for any thoughts!
Matt
Matthew D. Hancher
NASA Ames Research Center
Official: mdh at email.arc.nasa.gov
Personal: mdh at media.mit.edu
More information about the ODE
mailing list