Rotating an Object with velocity from World Orientation (BodyAngularVelocity)

I have a wheel that spins with BodyAngularVelocity. This wheel is connected to an axis piece that can point in any direction to rotate said wheel. I am intentionally avoiding constraints.

The Goal

  • The wheel should be able to rotate at a constant speed no matter which way it is facing in the world.
  • If the axis pivots on an x,z plane, the BodyAngularVelocity should be able to calculate how much velocity is needed on each axis to keep spinning the same way.
  • The velocity needs to be used as a velocity in world space, but based off the relative orientation of an axle part without changing the speed.

The Issue

  • When rotated, the wheel either slows down or switches rotational directions entirely.

Current Attemps

  • Multiplying by Right, Up, and Look Vectors
  • :ToObjectSpace() and :ToWorldSpace() (However this may have not been done in the right order or with the right CFrame calculations)

Useful Information

  • The wheel is a sphere part oriented at 90, -90, 0
  • The axle is a 1x1x1 part orientated at 0, -90, 0
  • An AngularVelocity x value makes the wheel rotate in the direction I desire (at current axle rotation)
  • The axle only rotates in the direction the wheel points. It will not spin with the wheel.
  • The surface of the axle that is forward is the Right surface.
  • The ball should not be used in any calculations. Only the axle.

image


Please notify me of any additional information I should provide that would be helpful to solving this. I have spent the past 5 days trial and erroring this with no successful result.

2 Likes

Here is a short paragraph describing the basic behavior of the AngularVelocity property on the BodyAngularVelocity wiki page

The AngularVelocity property (visualized above as a green line) controls the goal angular velocity of the applied torque: the direction of the Vector3 is the axis which the part rotates around, and the magnitude is the speed in radians/s .

Knowing this, your problem should be as simple as setting your AngularVelocity to the global RightVector (Or whatever other vector the motor is on) of your turning part, then multiply this vector by the speed to get the intended results

Example code would look something like:

--loop
bav.AngularVelocity = axle.CFrame.RightVector * desiredAngularSpeedRadiansPerSecond
------

If you want to convert studs per second to radians per second (assuming perfect traction and no gear ratio) you can use this simple formula:
image
Where:
vrps = Velocity in radians per second
vsps = Velocity in studs per second
r = Radius of wheel

Ended up overcomplicating it for all my attempts. It really was just as simple as using the LookVector (ended up not being RightVector for whatever reason). I kept thinking I needed to do something with CFrame and a simplified answer really helped.
Hopefully this helps anyone else who is trying to do the same thing.

1 Like