Aircraft lurches as it rotates

I have an aircraft with an automatically generated “Root” part at the centre of gravity (includes character), welded to an arbitrary part of the aircraft.
To turn the aircraft, I adjust the velocity of this root part.
However, the aircraft will lurch whenever I perform a rotation.
Anyone know how what causes this lurch? I have no idea where it comes from.

How are you rotating? CFrame? The rotation property?

Edit: I might have misread. When you say you rotate, are you adjusting roll or yaw?

I’d need to know exactly how you are rotating the aircraft first. Are you editing the raw RotVelocity? Or using something like VectorForce? BodyGyro? etc.

Roll or pitch.
Either way, it causes a lurch.

Raw RotVelocity, because BodyGyro is buggy.
I’ll consider using VectorForce.

Do you have a video of it doing so? I’ve encountered a bug where adjusting the Velocity and RotVelocity value in the same frame causes some very strange behaviour, but it wasn’t lurching, and it was fine if I was only adjusting RotVelocity.

How exactly do you adjust the RotVelocity? A discontinuous change of velocity is definitely going to give you a lurch, which is why adjustments to velocity are very often made indirectly via adjustments to acceleration or force.

I use BodyGyro a lot, and have not experienced any appreciable bugs with it. Are you sure that whatever issues you had with BodyGyros were bugs inherent in the gyro, and not either the code manipulating it’s CFrame value or some values of P and/or D that aren’t appropriate for the item being rotated?

An example clip of the behavior might be enlightening also.

3 Likes

I’m so certain the issue is a BodyGyro one that I’m pretty sure I know exactly what the bug is, given that the errors observed would occur for a BodyGyro that found rotation direction using vectors instead of CFrames.

I tried to reproduce the issue from what you described in OP, and I got something similar when using RotVelocity. The plane gets launched in a random direction when I try to change the RotVelocity instantaneously. I used a BodyForce to suspend the plane in midair.

Isn’t it weird that no one here has mentioned BodyAngularVelocity or Torque constraints? Those seem to work fine for me.

Do you have an easy repro case, for example, two CFrames (current and target) that will get the BodyGyro to do something undesirable, like rotate the wrong direction? I’ve only encountered the expected singularity that occurs at an exact reversal of the lookVector (a rotation of pi radians on any axis). Are you using Euler angles in your calculations at all? The issue of singularities with rotations of pi/2 radians is exactly why aircraft control systems use MRPs or quaternions.

Part.Velocity and Part.RotVelocity are best used as read-only properties. Setting them isn’t recommended, and IIRC, a sleeping part won’t take changes to these properties (e.g. setting a non-zero velocity on a stationary part won’t necessarily start it moving).

1 Like

This has worked in the past in Spring physics. Is this not the case in PGS?

A repro case I can suggested is a floating vehicle that you can pitch and roll with WASD keys
If it rotates through direct manipulation of its own CFrame, it will have no unexpected behaviours, even when using Euler angles.
If it rotates through manipulation of a BodyGyro CFrame, it will have erratic behaviour in a manner that suggests the BodyGyro class uses vectors internally. Obviously, setting the CFrame without Euler angles made no difference with my testing, since Euler angles were always producing the correct CFrames in the first place.

I’m pretty sure if someone just looked at the source code, there’d be some obviously poor maths that may have been the standard when the code was written. I can’t imagine the BodyGyro code has been examined in a long time, given that it’s from a previous generation of physics objects.

Can you create this repro? More critically, will you share this repro? Implementation is everything. Is your CFrame being calculated correctly? Is the parent of the BodyGyro oriented correctly? Have you properly tuned the PID (I thought this was going away in PGS but apparently it hasn’t?)? Is the center of mass of the aircraft in the proper place?

These are all things that need to be taken into consideration, and you have been quite tight-lipped about how you actually accomplished this “erratic behavior.” Like a good story, show, don’t tell.

As far as looking in the source code: it will be much easier for an engineer to find a problem if he or she knows what erratic behavior to test against. Since you have not provided a test case, it’s fairly pointless to suggest looking at the source code. Not to mention all the physics objects were reviewed during the creation of PGS Physics, which was fairly recent.

2 Likes

It’s going to be key to understanding the problem here, for sure. There is more than one way to get results that don’t match expectations, or instability in general. For example, you might expect a BodyGyro to always take a part from orientation A to orientation B via the path with smallest angular change, like a simple slerp tween would. Applied to a stationary part, this is what you should get for all but a pi radians change of orientation, and I haven’t seen a counter example. But as soon as you consider a part that already has angular momentum, and a BodyGyro with finite max torque, all bets are off and the “shortest path” from A to B in terms of angular change isn’t necessarily even a solution.

[Replying again to complexo here] I’m also not really sure what you mean by “using vectors instead of CFrames”. CFrames are a nice way to package up vectors both for making them fit the notation standards for linear algebra transformations, and for making the computations of all their dot products CPU and GPU friendly, but this is more of a notation and data structure issue. You can do the underlying math wrong with any choice of notation or data type.

There are too many unknowns to expect to just happen upon the same behavior. I’ve made vehicle and character controllers that use WASD and BodyGyro + BodyForce without encountering what you describe. Generally what we mean by a repro case is an already-existing example of a place that reliably exhibits the bug.

1 Like

Alright, I could upload one of my places early and set the vehicle to back to using BodyGyro instead of what I was working on.
I honestly just want to see the BodyGyro source code now though, it’s not the only misbehaviour I’ve seen in the class and I’m really curious as to how such a simple class can be so erratic.

I may actually have a place that demonstrates what he’s talking about, but @complexo hasn’t really explained his issue at all so it’s hard to say.

BodyGyro does not take a torque-minimal path, which can be seen in this place here:

Grey balls represents the path the brick takes, and green balls represents the nlerp path, which is assumed to be the shortest arc across a sphere.

At the equator, the path a BodyGyro takes is very similar to the nlerp arc:
image

near the poles however, relatively large deviations can be observed even for short paths:


image

Large changes in direction can even cause the Body Gyro to start rotating away from the target:
image

The BodyGyro appears to have a preference for getting its equator aligned with the target before rotating around its pole to reach the target:

I can’t even explain this one:
image

The BodyGyro involved has a MaxTorque of (20,20,20), a Proportional term of 30, and a Derivative term of 15.

It’s possible that the airplanes @complexo created do not use Roblox’s standard orientation (i.e. “Up”, “Front”) for its BodyGyro part, creating irregular behavior.

Alternatively I could be over-complicating things and he’s only complaining about the bounce that occurs when you increment the BodyGyro direction a small amount, which is completely expected for underdamped PID systems.

1 Like

I’m not complaining about bumps for small BodyGyro increments, I’m complaining about bumps for continuous rotation. I have zero problems when doing small increments.

Also, since you’ve constructed such an easy to visualise repro case, can you add a third arc colour using a different algorithm?
One where each iteration sets the part’s orientation to currentAngles + rotationAmount*(goalAngles-currentAngles).Unit
I’m curious as to how similar that is to the BodyGyro algorithm.

And maaaaybe a fourth one that controls velocity instead of angles, but that’s only if the results of the first vector-based algorithm closely resemble the BodyGyro algorithm, there’s no point if it’s totally different.

You’re going to have to write a more complete algorithm than that. Your inputs are the starting vector and the ending vector.

Also, I don’t recommend BodyGyro for continuous rotation, even setting it incrementally like I mentioned. BodyGyros are meant to point at a specific location; a BodyAngularVelocity is meant to rotate the body at a continuous rate.

The only inputs are the ending vector and rotation per iteration actually, the current vector instead of the starting vector is used.
I’m pretty sure it’ll work as a simplistic gyro algorithm, I’m just curious as to whether it’ll give insight into how BodyGyro works and that’d take side-by-side comparison.
I’ll test it to check that it works.

Nah man I’m not going to try to interpret what you’ve written and then be told I did it wrong, since you haven’t even described the algorithm fully, like rotationAmount. The place is now uncopylocked; you can modify it just as easily as I can.

1 Like