Calculating instantaneous G-force/acceleration on rigidbody3d with linear and angular velocity

Godot Version

4.5.1

Question

hey All

i have a rigidbody3d airplane model (nose facing local -z direction) for a simple flight sim and am trying to compute the instantaneous G force on the plane (primarily in the local +y direction).

the first approach multiplies the linear velocity along the nose direction and angular velocity around the pitch axis:

accel = linear_velocity.dot(-global_basis.z) * angular_velocity.dot(global_basis.x)

the second approach computes the “general” acceleration vector and then resolves it in the local y direction:

accel = -linear_velocity.cross(angular_velocity).dot(global_basis.y)

i would expect these two approaches to give the same result, but they don’t except for the simple case (eg travelling forward and pitching up). something like a barrel roll results in different values.

i must be missing something basic (also rusty in this topic), so seeking help from the community.

thanks

Shouldn’t the first approach be the magnitude of cross products of projected vectors, instead of scalar product of projected vector magnitudes?

thank you, normalized.

just to confirm, is this the expression that you mean?

accel3 = linear_velocity.project(-global_basis.z).cross(angular_velocity.project(global_basis.x)).length()

it gives the same output as the first approach. i think this is expected since the two projected vectors are orthogonal, and the projected lengths are just the dot products.

edit: it is same as the first approach in terms of magnitude, but the signs can be different.

Can you even combine linear and angular velocities like that? I think you first need to calculate the linear velocity/acceleration (from angular velocity) of the point that represents the cockpit. Afaik that’s ω x (ω x P), where omega is angular velocity and P is the local point position.

Does that formula give you ‘absolute’ acceleration ?

Cant really help much i usually just cheezed my way through the math in godot because i got confused by all the different variables for position.

You might need a jacobian or something…

you got me thinking about the dimensions (angular_velocity is in radians even though the inspector UI shows it in deg/s).

i’m using the a = v*v/r formula for instantaneous angular acceleration in a circular path (v is tangential velocity, r is radius). but since v = rw, i can substitute and get a = v * (rw) / r = vw. the dimensions seem compatible: m/s2 == m/s * rad/s == m/s2.

i think i found a problem with approach 1. i only considered velocity in -z axis direction, but also need to consider the x axis too, since they both are perpendicular to the y axis as well as contribute to the g-force/acceleration. so i think the formula is:

accel1a = linear_velocity.dot(-global_basis.z) * angular_velocity.dot(global_basis.x)
accel1b = linear_velocity.dot( global_basis.x) * angular_velocity.dot(global_basis.z)
accel1 = accel1a + accel1b

this turns out to give the same results as approach 2 (which is much more succinct)

accel2 = -linear_velocity.cross(angular_velocity).dot(global_basis.y)

thanks for the response again.

2 Likes

i believe approach 2 should give you instantaneous acceleration in global space. then, just resolve it to the local axis as needed (accel2.dot(global_basis.y) for airplane Gs)

1 Like

The radius is the radius of curvature of the space curve traced out by the airplane, you could sample the previous position and orientation to compute the center of curvature and radius, but that would hardly be optimal. So the gforce is defined by the swing about these virtual centers.

a = v^2 / r … That looks like the centrifugal acceleration, and that appears as an additional term when computing acceleration with change of coordinates, thats why they call it a ficticious force…

The centrifugal acceleration is also w^2 *r .

Then you could get a = vw so

a = vw = w^2 r, therefore r = v / w

But thats in the direction towards the instantaneous center of rotation, you could either take a sample from last frame or rake a closer sample by computing some intermediate steps.
Then get the linear velocity from the last frame and compute the angle to the linear velocity from this frame.

the center of curvature is in the direction of the principle normal,

dT/ds = N / r 

So using the linear velocities, normalize them, subtract them, divide by the difference in positions and multiply by the radius to get N …

Then the centrufugal force points in the direction of negative N. (N is a vector)


Fc = - m*|v|*|w|*N 

yes, i was trying to calculate the g-forces on the plane. i think i used the wrong term “angular acceleration”, it should be radial acceleration, towards the center of the imaginary circle.

it also turns out that linear_velocity and angular_velocity are properties of rigidbody3d, so i didn’t need to compute them using different frames.

thanks.

Then you divide your number by 9.81 m/s^2 to convert to G’s.

The acceleration is typically written:

a = (dv/dt) e_1 + k v^2 e_2

With e_2 as the principle normal, e_1 as the tangent, k is the curvature.

Id assume in this case the force you feel is a reaction force against the direction of the craft, like the stomach dropping when an elevator moves upwards.

Thats the way its done. The only thing i would point out is that many games have airplanes thaf rotate about thier own y axis and so the principle normal isnt always the local y.of the frame basis of the craft.

Also because G- forces are non newtonian there are additional calcilation problems. All that works in the plane in 2D as well.

  • but they exist regardless and you could easily take advantage of the physics engine producing them as an emergent property. It all looks different when youre sat on a plane - or the airplane.

JSBSim as a GExtension would take care of the flying part, it’s been used in serious sims.

1 Like

thank you, pizza guy and olenic!