[ODE] Joint forces

Anselm Hook anselm at hook.org
Wed Aug 28 12:29:01 2002


Hi,

Just a general comment about callbacks - I see they are not being used
much in ODE but I wanted to just add additional encouragement not to use
them.

I've found that when building extremely large applications such as
commercial networked video games that specialized callbacks are quite
debilitating, and are almost an anti-pattern.  The problem is that for any
project that breaks new ground there is never a clearly defined API from
day one, and API revision is to be expected.  Callbacks make code brittle
because they have to be passed explicitly to the API layer - later
upgrading the API means retrofitting all the code that referenced the old
API - API object constructors get passed new callbacks for example.  As
well one ends up with dozens of dangling filaments that extend across the
API boundary and corresponding dozens of receiving methods on the other
end.  Usually all of those pipes have to be routed to a single state
engine and this means creating a structure that is a union of all the
different kinds of callbacks anyway.  Non specialized callbacks or
'generic event handlers' are a better pattern because one can choose to
route all events to a single event observer, and the engine can introduce
new events without breaking pre-existing code.  As well by marshalling
args into structs it becomes easier to network event transitions.  If the
API code is built out initially with the ability to register generic event
observers then usually it doesn't have to be revised again (at least in
that way).  Hope this isn't terribly unclear or repeating things that
everybody already knows.

 - a


I've found that when building extremely large applications that it's
better to use a generic event structure with specialized event details
tagged onto the end.


On Wed, 28 Aug 2002, Erwin de Vries wrote:

> > > Attached are the patches for the src and include dirs.
> >
> > i have some questions ... the dJointCallback returns an int. if the int
> > is nonzero then the joint forces are added to the body, else they're
> > not. what are you trying to achieve with this interface? if it's
> > selective joint deactivation then this is not the way to go about it ...
> > setting the joint force to zero will not remove the effect of the joint,
> > as it's constraint will have already been factored into the force
> > computations for the other joints. you will get some kind of wierd
> > "quasi-joint" this way. to deactivate joints, the existing interface
> > should be used *between* time steps.
>
> The main reason for the option to disable a joint's effect on the current
> step is to fix LCP errors. You can easyly detect an invalid force or torque,
> and then simply return 0 to 'fix' the problem. I do this checking for all my
> joints, and it works.
>
> > hmmm, i sometimes find callbacks a bit messy, what about if this was the
> > API:
> >
> >    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;
> >
> >    void dJointSetFeedbackMode (dJointID, int mode);
> >    const dJointFeedback *dJointGetFeedback (dJointID);
> >
> > when dJointSetFeedbackMode() sets the mode to 1, dJointGetFeedback() can
> > be used to get the joint feedback information *after* the step has
> > completed. this API is more easily extensible - we can add fields to the
> > structure without breaking old code (although the callback could be
> > passed a structure too).
>
> So inside the joint a dJointFeedback* will be kept, and this pointer will be
> initialized when the mode is set to 1. It will be filled at the same place
> the callback in my code is generated, and the user can get it after the
> step. Sounds reasonable (if LCP problems were solved). What about contact
> joints? They are created for every step. Setting the mode for every step
> would mean you have to allocate these 64 bytes for each joint for each step.
> Right?
>
> > it's also not clear what the callback behavior
> > should be for higher order integrators.
>
> I cant comment on that. ;-)
>
> _______________________________________________
> ODE mailing list
> ODE@q12.org
> http://q12.org/mailman/listinfo/ode
>