Godot Version
4.6.1 (double precision build)
Question
Hi everyone,
I am trying to verify some calculations for a pilot AI against the engine, so I’m currently writing some test scenarios.
I am struggling a lot when it comes to angular acceleration, specifically the moment of inertia. It probably doesn’t help that my math isn’t great, so please excuse any obvious errors.
I have prepared a small test scene that you can find here: GitHub - RinneT/godot-angular-physics-test: Test scenario for calculation of angular movement in Godot · GitHub
Note that while I use a double precision build of Godot, that should not be required to run the scene.
I have written two functions to calculate
- the rotation in radians after constant acceleration in rad/sec² over a given time in seconds.
- the torque in Nm required to achieve the constant acceleration
## Calculate the Angular rotation after time (along a single axis)
## https://www.sciencing.com/revolutions-angular-acceleration-5805078/
## Params:
## angle_start: Starting angle of the object
## ang_velocity_start: Starting angular velocity
## acceleration: constant acceleration
## time: time
func get_rotation_from_angular_acceleration(angle_start: float, ang_velocity_start: float, acceleration: float, time: float) -> float:
return angle_start + ang_velocity_start + 0.5 * acceleration * pow(time, 2)
## Get the torque required for a given acceleration
## Params
## moment_of_inertia: Moment of Inertia in kg/m²
## accelertaion: acceleration in rad/sec²
func get_torque_for_acceleration(moment_of_inertia: float, acceleration: float) -> float:
return moment_of_inertia * acceleration
As input, I need the moment of inertia, which I get via:
PhysicsServer3D.body_get_direct_state(test_capsule.get_rid()).inverse_inertia.inverse()
I know that I can also get it via the inertia_tensor, but the values are the same.
Currently I restrict any acceleration to the x-axis for simplicity.
Unfortunately, the resulting acceleration is far off from what is predicted.
I wonder if the moment of inertia unit is wrong. For the formula above, it needs to be in kg/m².
I also notice that there is a strong difference between applying torque each tick, and setting a constant torque once.
The test scene in the Github repo has a toggle to switch between the two.
I apply the torque as follows (not ideal, but I thought it works as a test case):
## Not very efficient, but this is a proof of concept, after all
func _process(delta: float) -> void:
if (apply_torque_constant && constant_torque.is_equal_approx(Vector3.ZERO)):
add_constant_torque(requested_torque)
else:
apply_torque(requested_torque)
Any help to understand what is happening and if I’m doing anything fundamentally wrong would be greatly appreciated.