[ODE] Controlling an avatar and the use of AMotors

Patrick McColgan patrick at torcinteractive.com
Wed Nov 10 11:24:46 MST 2004


Thanks for the reply Geoff (to whom I sent this mail twice, sorry), I 
think the biggest problem has been that there doesn't seem to be strong 
documentation on AMotors and especially in User mode.  The list has a 
lot of unanswered calls for information on this so I'll post my findings 
on the user mode and any advice from people with experience would be 
appreciated.

I got the AMotor fix you contributed, it was added to ODE on September 
29th and is in the CVS repository now.

Basically I got dAMotorEuler working fine (there's some code in 'test 
joints' app), it was a good insight into what the amotor was actually 
doing  but wasn't particularily robust so obviously dAmotorUser is the 
desired approach for custom application.

In my application I created two bodies (spheres) and created an amotor 
between so that I would hopefully get a good idea of the effects on both.

Firstly I set up up the joint with the 3 standard axis (x, y and z) and 
set all the axis angles to zero.  Probably the most obvious 
misconception, certainly mine, was that when the documentation says you 
have to control the axis it really means it, you have to update the 
angular differences between the axis of the two bodies in the joint.  So 
each frame I calculated the angular difference about yaxis by getting 
the dot product of the unit vectors in the direction each body was 
facing which returns the cosine of the angle between them.  The angle 
was in the range of 0 to pi in either direction so it also needs a way 
to differentiate a positive and negative side, in mine a positive 
rotation is anti-clockwise so to rotate clockwise you need a negative 
angle which cosecant can't deliver.  I tried to extract the angle from 
the body's matrix but this only returned an angle between zero and half 
pi, I don't quite understand why this is, its the same as the angle 
range in Euler mode for axis 1.  Anyway having got the separation angle 
magnitude I took the cross product of the two directional unit vectors 
to determine the winding order.  If the cross product gave a positive 
normal vector in the y axis (up axis) it can be assumed that the angle 
is clockwise and hence negative whereas if the normal has a negative up 
value it is an anti-clockwise winding order and the angle can be left 
positive.  This angle is then set by hand as the angle for the axis 
defined as up.  I hope that makes sense, I see it as the greatest 
stumbling block but hopefully if nothing else people will see that you 
must compute the angle difference for every change in the axis.

This makes the bodies respond at least which after many hours of still 
objects was very pleasing.  But I still haven't got the hang of amotors 
yet.  Part of the problem may be my abstraction to only rotations about 
the y axis just now but I'll continue to work on it and hopefully I'll 
leave a trial of my trials and errors that future users may find helpful.

My problem now is applying torque to the axis;  The axis are defined 
relative to body one, if I rotate body one (not the axis of the joint 
but the body itself) it returns the correct angle difference between the 
directions.  However if I apply the torque to the axis (as opposed to 
the body) the body itself turns normally and stops but the second body 
seems to accumulate the force over time even though I damp the torque 
and the first body slows to a halt.  I am not using stops, when I do it 
becomes really strange, any thoughts?

Thanks.,

Geoff Carlton wrote:

I've got a basic working system using the ccylinders and AMotor.  Its 
may not be optimal, but it works and thats been good enough so far.

I create the AMotor with user setting, axis set to standard X,Y,Z locked 
to the body (in my game +Z is up, and the character spawns standing 
upright).   Now, firstly you'll want to check your ode has a recent 
AMotor fix for user angles (posted here a while back).  To use the 
AMotor, I work out the angles myself and plug in desired velocities for 
each of the 3 axis.

Now by setting Vel on axis 3 you can control its rotation around its 
local up (ie its facing).  To calculate the Vel you have to consider 
where the character is facing and where you want it to face and consider 
the difference, and translate that into a desired velocity.  I only do 
this when the character is mostly upright, which makes the comparison 
easier (you can flatten the vectors so that z=0 before considering the 
difference).

By setting Vel on axis 1 and 2 you can add forces to try to keep it 
upright.  To do this you need to rotate the body around the shortest arc 
to get it back to upright, which is the cross product of local up and 
world up.  This needs some extra checks and scaling (e.g. if the guy is 
on his head, just pick any angle).  I look at the modified cross product 
and pull out the x and y components to plug in as axis 1 and 2 Vel.

I'm not sure whether this is what anybody else does, so I'd be curious 
to hear of alternate solutions.  In particular, it seems to have trouble 
when rotating the facing while trying to get up, it twists on the ground 
and struggles to right itself.  I got around this by not turning the 
facing unless the capsule is mostly upright (so its really only doing 
either twisting, or uprighting, never both).  Also, when I was 
experimenting I found it easier to set up the user angles and plug in 
fixed Vel values and make sure its spinning the right way before trying 
to come up with a proper set of solutions for it (e.g. plug in a fixed 
value for axis 3 and see the capsule spin its facing around - gives you 
encouragement for continuing on!).

Geoff

Patrick McColgan wrote:

> Hello
>
> I'm trying to develop a character controller in ODE, I've already gone 
> through the mailing list and read similar queries.  The recommended 
> approach for maintaining something like a vertically standing cylinder 
> is to use an amotor however I have extensively searched the mailing 
> lists and beyond this recommendation there isn't much more support for 
> the use of amotors themselves and their use in such a situation.
>
> I haven't found the ODE manual particularily clear when discussing 
> amotors either.
>
> At the minute I have implemented an amotor between a sphere and the 
> environment (i.e. nothing) and use dAmotorEuler (defining global y and 
> x axis as the first and third axis) so it automatically defines the z 
> axis as the second axis.
>
> From this it can return the relative rotations from the sphere's local 
> axis and the global axis as Euler Angles.  Is this essentially what an 
> amotor does?  Just returning the difference?  I don't find the use of 
> Euler angles particularily useful.
>
> I'd really appreciate if anyone had a more detailed approcah for the 
> application of AMotors to maintain an avatar (i.e. keeping something 
> like a cylinder upright).
>
> Thanks
> _______________________________________________
> ODE mailing list
> ODE at q12.org
> http://q12.org/mailman/listinfo/ode
>
>

_______________________________________________
ODE mailing list
ODE at q12.org
http://q12.org/mailman/listinfo/ode


More information about the ODE mailing list