Keeping an object facing a specific direction using forces

Discuss any questions about BEPUphysics or problems encountered.
Post Reply
mcmonkey
Posts: 92
Joined: Fri Apr 17, 2015 11:42 pm

Keeping an object facing a specific direction using forces

Post by mcmonkey »

Time to ask a general physics coding question in the forum for the specific physics engine in use even though a mathematical forum might make more sense... were a quality one to exist :/

So I have an object floating in the air.
This object can be knocked about by any number of exterior factors.
This object has one goal in its existence: To keep it's top oriented upward. Meaning, if it were EG a flat platform, that platform would remain facing the correct upwards direction.
However it has a limit: It must apply a restricted amount of force to accomplish this goal. Meaning it applies forces to slowly rotate itself back to its goal orientation (as opposed to teleporting instantly or anything).
It also doesn't care about it's yaw angle (The rotation about the up/down axis).

How would I go about calculating and applying the necessary force? I have a nice little SingleEntityConstraint sub-class that can successfully spin it out of control in a variety of entertaining ways, but none of them seem to spin it towards the goal direction (instead, they spin carefully AWAY from the goal direction at all times (and then spin the opposite direction away from the goal if I negate it, of course).

As a final note, "Up" is an arbitrary direction and may change, even actively moving during the simulation.

Thanks in advance for any hints!
mcmonkey
Posts: 92
Joined: Fri Apr 17, 2015 11:42 pm

Re: Keeping an object facing a specific direction using forc

Post by mcmonkey »

Oh side note, I donated $50 to BEPU. It's a small fraction of what you deserve for the amazing help you've given (not to mention building an amazing physics engine in the first place), but it's a start :P


One day maybe I'll be rich from selling games, and you'll get a fair piece of the pile :P
Norbo
Site Admin
Posts: 4929
Joined: Tue Jul 04, 2006 4:45 am

Re: Keeping an object facing a specific direction using forc

Post by Norbo »

Two things are needed: an axis around which to apply the torque, and some measurement from which the desired torque can be derived.

To get the axis, take the cross product of the target up vector and the object's current up vector. To get the angle between the two directions, use the property of the cross product that:
||a x b|| = ||a|| * ||b|| * sin(angle)
So, if the target up vector and current up vector are both normalized, the angle between the target and current vectors is just asin(cross(a, b).Length()). That length calculation can also be used to then normalize the axis. (Be careful about a zero length axis; that will happen when the current and target vectors are parallel. In that case, no spring force is required since it's already at the goal.)

You could now apply a torque of axis * -angle and it would try to close the gap. However, you'll probably want to tune the behavior a bit more than that- perhaps with stiffness and damping. You can treat it as a one dimensional spring, following torque = axis * (stiffness * (-angle) - damping * angularVelocity). You'll want to use the one dimensional angular velocity around the axis for the damping component, which you can get from taking the dot product between the entity's angular velocity and the spring axis.

The stiffness and damping values have limitations- you can't go too high without introducing oscillations that blow stuff up. If the platform is pretty heavy relative to the things affecting it such that the spring doesn't need to do any really fast corrections, this will probably work with no further effort.

If really stiff values are required, a constraint that lives in the solver may be required. It follows the same basic lines as the above derivation, but requires phrasing the problem in terms of velocity constraints. I would recommend just trying the non-constraint approach first to see if it works.
Oh side note, I donated $50 to BEPU. It's a small fraction of what you deserve for the amazing help you've given (not to mention building an amazing physics engine in the first place), but it's a start
Thanks a bunch :D
Post Reply