# Bug Pitching Bug

Discussion in 'Physics' started by kamber0ff, Mar 23, 2023.

1. ### kamber0ff

Joined:
Dec 17, 2022
Posts:
6
So I have a controller for an airplane that I created. And for pithing up and down it applies a certain amount of force at a certain point. In theory it sounds good but for some reason when I pitch up to around 90 degrees in either direction it just stops pitching and it returns back to 0 degrees. But there is also that in the same scenario if I change the direction to the opposite direction at that 90 degrees it now completes the full maneuver. And it's the same for rolling. The points at which the force is applied are children to the control surfaces so they change their position according to the aircraft. And the direction of the force applied also think is correct.

Code (CSharp):
1. nat_wing_lift = 1f/2f * rho * aircraft.velocity.magnitude * wing_area * nat_cl;
2. nat_stab_lift = 1f/2f * rho * aircraft.velocity.magnitude * stabilators_area * nat_cl;
3.
4. nat_lift = new Vector3(0, nat_wing_lift + nat_stab_lift, 0);
5. //nat_lift is the total force that will be applied to the aircraft
6.
7. aircraft.AddForceAtPosition(new Vector3(0, left_wing_lift, 0), Left_Wing_Force_Point.position);
8. //and this is when steering
Do you have any idea why this happens. The game currently doesn't calculate or apply any drag.

2. ### arkano22

Joined:
Sep 20, 2012
Posts:
1,501
Disclaimer: I have absolutely no idea about aircraft physics, but if you add a force that points up/down in world space (Y axis, like in "new Vector3(0, left_wing_lift, 0)") to a point that's off the center of mass of a body, at exactly 90º the force is aligned with the vector that goes from the point to the center of mass so it would stop causing any angular acceleration.

Going from 90 to 0 degrees instantly sounds like you're dealing with angles explicitly at some point in your code though, since rigidbodies just won't do this under normal circumstances.

Could you share a bit more of your code? what you've shared so far does not give any useful information (nat_lift is not used at all, all you do is AddForceAtPosition passing a vector aligned with the world space Y axis).

3. ### karliss_coldwild

Joined:
Oct 1, 2020
Posts:
459
AddForceAtPosition expects a vector in world coordinates. Which means that your code is always applying the lift upwards, instead of perpendicular to movement direction. Pressure difference doesn't care about direction of gravity.

For somewhat realistic simulation you might also need to take into account velocity direction since it isn't necessarily always be identical to forward direction of airplane. During normal flight they will be quite close, but I would expect that when making more dynamic maneuvers where momentum takes a significant factor the difference could be quite large. (If that's already taken into account when calculating nat_cl or area then it's fine)

4. ### kamber0ff

Joined:
Dec 17, 2022
Posts:
6
Well the force point is supposed to change it's position and rotation since it's attatched to the wing and in my head it should never align with the centre of mass of the airplane maybe the AddForceAtPostition() method doesn't apply the force in the way I was thinking

5. ### karliss_coldwild

Joined:
Oct 1, 2020
Posts:
459
Yes AddForceAtPosition expects force vector in world coordinates, just like the position itself (you have that one correct). It's the first thing listed in the documentation for that function. When in doubt and something confusing is happening, check the docs and validate that your assumptions are correct https://docs.unity3d.com/ScriptReference/Rigidbody.AddForceAtPosition.html

6. ### kamber0ff

Joined:
Dec 17, 2022
Posts:
6
Maybe a solution would be to add rigidbodies to the control surfaces and somehow attach them to the main rigidbody and then use AddRelativeForce() on them?

7. ### arkano22

Joined:
Sep 20, 2012
Posts:
1,501
A much simpler solution is to just convert your force vector to world space using TransformVector.

kamber0ff likes this.
8. ### kamber0ff

Joined:
Dec 17, 2022
Posts:
6
How can I use TransformVector to fix it? Cuz I cant find anything to help me

9. ### arkano22

Joined:
Sep 20, 2012
Posts:
1,501
Code (CSharp):
1. var worldSpaceLift = aircraft.transform.TransformVector(new Vector3(0, left_wing_lift, 0));

kamber0ff likes this.
10. ### kamber0ff

Joined:
Dec 17, 2022
Posts:
6
THANK YOU SO MUCH NOW IT ACTUALLY WORKS AND FLIES

arkano22 likes this.
11. ### arkano22

Joined:
Sep 20, 2012
Posts:
1,501
I'd recommend to spend some time understanding vector spaces (local vs world) and how to convert data between them (in Unity you can use transform.TransformVector/Direction/Point and InverseTransformVector/Direction/Point instead of dealing with change of basis matrices directly) as they are one of the fundamental pillars of 3D math, required for both graphics and physics. You need to get intimately familiar with these!