Rotational force applied around center of mass

I have a free-floating object that I want to control the rotation of with Torque, but a torque applied to only one axis of rotation results in uncontrolled spinning of the object on multiple axes. I’m assuming this is because Torque is not applied around the center of mass, as this happens even with Workspace.Gravity = 0.

https://gfycat.com/ForsakenShortHart

I do not want to use AlignOrientation, as it has the same problem with rigidity disabled. I could switch on RigidityEnabled to control everything with CFrame, but then I run into issues with large forces making the turning more violent than I intended in scenarios that would hinder a static-value Torque.

It would be nice if there was a rotational force constraint we could apply around the CoM to stably rotate the object without resorting to rigid forces or weird proxy controls for speed.

3 Likes

I think this is unstable for an actual, physical reason – not just a glitch in the engine. The rotational force is being applied to the center.


There’s a fascinating video showing this behavior in space 75% of the way down the page.

So you have two ways to solve this:

  1. Weld on some parts so the axis you’re spinning on has either the greatest or smallest moment of inertia (smallest seems easiest – weld some parts on each side of the cart).

  2. Use an align orientation or some other technique to correct against the unstable rotation.

Non-symmetric rotational Inertia makes it so that torque applied on a single axis will cause rotation around other axes. That’s just physics.

But why can’t you use AlignOrientation with rigidity disabled?

The same thing happens – it rotates around multiple axes instead of one, attempting to reach the target orientation.

So you are saying that the object is only allowed to rotate around one axis?

Correct e.g. a starship turning left/right on the yaw axis only. I don’t want it to roll or pitch up and down for the most part, unless it’s ascending or descending at the same time.

So here is what you do: AlignOrientation with:

  • PrimaryAxisOnly = true
  • RigidityEnabled = true
  • ReactionForceEnabled = true
  • Attachment0 on your moving object
  • Attachment1 on an anchored part (or terrain)
  • The primary axis of the Attachment0 pointing along your yaw in object space
  • The Attachment1 with its primary axis in the direction that the yaw should point
    Your body will now only rotate around it’s yaw axis, and this axis is fixed in world space
3 Likes

If you need to control the Yaw with a smooth motion, add a second AlignOrientation constraint with

  • RigidityEnabled = false
  • ReactionForceEnabled = true
    This will be in charge of applying torques to orient your body
1 Like

Verified that does the trick, but this seems overcomplicated for such simple goal. Without a complicated configuration of constraints and awkward proxy controls, I found I’m able to achieve this by just setting RotVelocity to a local-to-world transformed vector on Stepped. Are there any downsides to setting the property directly (e.g. breaking interpolation / etc) compared to an AlignOrientation?

primary.RotVelocity = primary.CFrame:vectorToWorldSpace(Vector3.new(0,turnSpeed,0))

https://gfycat.com/OilyElectricAmericancrayfish

Yes there are downsides to clearing the components of the velocities in that each time this is done, the physics solver is not getting the velocities that it expects leading to potential instabilities and performance issues. By using the constraint you tell the solver exactly what you need.

Also the script On Stepped will run at much lower frequency than the physics update.

1 Like

What does the Responsiveness property of AlignOrientation/Position do? The wiki lists it as how quickly the constraint will reach its goal, so it sounds like it determines how much torque up to MaxTorque to apply, but there’s not enough information to know anything more than that. I’m wondering:

How can I determine how much torque/force will be applied, given MaxTorque/Force and Responsiveness? The vague description on the wiki isn’t much to go on.

How can I calculate the optimal Responsiveness to avoid overshooting the goal, given MaxTorque/Force? Due to its awkward scale (5-200), using it has become a weird balancing act similar to the problem with the D/P properties of legacy body movers.

Responsiveness is like the D/P params on the legacy joints, it needs to be tuned to your situation (at least now we only have 1 param to tune). I could give you the equation for this parameter but it wouldn’t give you anything as it depends on a lot of things (masses, inertias, presence of other constraints). So the best way is to tune it by trial and error.

  • Responsiveness is for how fast the constraint achieves the orientation
  • MaxTorque is how strong the constraint is with respect to the environment and how large is the overshooting

I usually tune this as follows:

  • set MaxTorque to something very high (say +inf)
  • tune Responsiveness by trial: this determines how fast the constraint achieves its target
  • reduce the MaxTorque until the collision response with other parts is acceptable but before the overshooting is too large
2 Likes