[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