Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Aircraft(Rigid Body) Center of Mass Issue

Discussion in 'Physics' started by BradMick, Dec 29, 2015.

  1. BradMick

    BradMick

    Joined:
    Apr 2, 2014
    Posts:
    113
    Howdy all,

    I'm having a problem with the center of mass of my Rigid Body object. Essentially what I've attempted is to set the Rigid Body Center of Mass equal to the GameObjects transform.position. This didn't work as intended, as all the forces were applied in really bizarre ways. I then hit upon TransformDirection and InverseTransformDirection as well as TransformPoint and attempted to use those, as the Rigid Body works in World Space versus Local Space (or at least that's why my research has led me to conclude). So what I've got now is the Rigid Body Center of Mass being updated based on a transformed local position. Things are definitely off. Attached is a screenshot showing the results of the code as it sits now as well as the most up to date code.

    I have one working theory, and that is that I have to specify the directions of the transforms after running the InverseTransformDirection...because just looking at what's happening once the thrust is applied, is it's acting like all the forces are being applied in the wrong directions.

    The key lines I'm sure are the culprits start at line 47 and end at line 53.

    Definitely need an assist on this one...because it's got me stumped.

    V/R

    Brad

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Airplane : MonoBehaviour
    5. {
    6.     Rigidbody RB;
    7.  
    8.     public float Pitch = 0.0f;
    9.     public float Roll = 0.0f;
    10.     public float Yaw = 0.0f;
    11.  
    12.     public float Thrust = 0;
    13.  
    14.     public float C_L = 1.5f;
    15.     public float Rho = 1.225f; //kg/m3
    16.     public float S = 16;
    17.  
    18.     private Vector3 RBVelocity;
    19.     private Vector3 RBLocalVelocity;
    20.  
    21.     private float Lift;
    22.    
    23.     Vector3 CoM;
    24.     Vector3 RBCoM;
    25.  
    26.     Elevator[] Elevator = new Elevator[2];
    27.     Vector3[] ElevatorHinge = new Vector3[2];
    28.     Vector3[] ElevatorForce = new Vector3[2];
    29.  
    30.     Aileron[] Aileron = new Aileron[2];
    31.     Vector3[] AileronHinge = new Vector3[2];
    32.     Vector3[] AileronForce = new Vector3[2];
    33.  
    34.     // Use this for initialization
    35.     void Start()
    36.     {
    37.         RB = GetComponent<Rigidbody>();
    38.         Elevator = GetComponentsInChildren<Elevator>();
    39.         Aileron = GetComponentsInChildren<Aileron>();
    40.     }
    41.    
    42.     void FixedUpdate ()
    43.     {
    44.         Pitch = Input.GetAxis("Vertical");
    45.         Roll = Input.GetAxis("Horizontal");
    46.  
    47.         Vector3 currentPos = transform.position;
    48.  
    49.         CoM = transform.InverseTransformDirection(currentPos);
    50.  
    51.         RB.centerOfMass = CoM;
    52.  
    53.         RBCoM = RB.centerOfMass;
    54.  
    55.         ElevatorHinge[0] = Elevator[0].transform.position;
    56.         ElevatorHinge[1] = Elevator[1].transform.position;
    57.  
    58.         ElevatorForce[0] = Pitch * (Elevator[0].transform.up * Elevator[0].elevatorForce);
    59.         ElevatorForce[1] = Pitch * (Elevator[1].transform.up * Elevator[1].elevatorForce);
    60.  
    61.         RB.AddForceAtPosition(ElevatorForce[0], ElevatorHinge[0]);
    62.         RB.AddForceAtPosition(ElevatorForce[1], ElevatorHinge[1]);
    63.  
    64.         AileronHinge[0] = Aileron[0].transform.position;
    65.         AileronHinge[1] = Aileron[1].transform.position;
    66.  
    67.         AileronForce[0] = Roll * (Aileron[0].transform.up * Aileron[0].AileronForce);
    68.         AileronForce[1] = -Roll * (Aileron[1].transform.up * Aileron[1].AileronForce);
    69.  
    70.         RB.AddForceAtPosition(AileronForce[0], AileronHinge[0]);
    71.         RB.AddForceAtPosition(AileronForce[1], AileronHinge[1]);
    72.  
    73.         RBVelocity = RB.velocity;
    74.         RBLocalVelocity = transform.InverseTransformDirection(RBVelocity);
    75.  
    76.         float ForwardVelocity = RBLocalVelocity.z;
    77.         float UpVelocity = RBLocalVelocity.y;
    78.         float SideVelocity = RBLocalVelocity.x;
    79.  
    80.         Lift = C_L * 0.5f * Rho * S * Mathf.Pow(RBVelocity.magnitude, 2.0f);
    81.  
    82.         RB.AddForce(Lift * transform.up);
    83.  
    84.         RB.AddForce(Thrust * transform.forward);
    85.  
    86.         Debug.DrawLine(RBCoM, ElevatorHinge[0], Color.green);
    87.         Debug.DrawLine(RBCoM, ElevatorHinge[1], Color.green);
    88.  
    89.         Debug.DrawLine(RBCoM, AileronHinge[0], Color.green);
    90.         Debug.DrawLine(RBCoM, AileronHinge[1], Color.green);
    91.  
    92.         Debug.DrawRay(ElevatorHinge[0], ElevatorForce[0], Color.red);
    93.         Debug.DrawRay(ElevatorHinge[1], ElevatorForce[1], Color.red);
    94.  
    95.         Debug.DrawRay(AileronHinge[0], AileronForce[0], Color.red);
    96.         Debug.DrawRay(AileronHinge[1], AileronForce[1], Color.red);
    97.     }
    98. }
    99.  
     

    Attached Files:

  2. Todd-Wasson

    Todd-Wasson

    Joined:
    Aug 7, 2014
    Posts:
    1,079
  3. Zoomrail2

    Zoomrail2

    Joined:
    Feb 17, 2023
    Posts:
    1
    Bro I was wondering what it meant by relative. Thanks for the explanation that is 200% better than stupid document.
     
  4. dwatt-hollowworldgames

    dwatt-hollowworldgames

    Joined:
    Apr 26, 2019
    Posts:
    104
    I would also advise you that AddForceAtPosition is incompatible with FloatingOrigin. An origin shift will cause your aircraft to turn violently for a moment due to the forces being based at a world position that has moved. I overcame the issue by finding a function that would compute a torque from a force.

    Code (CSharp):
    1.  
    2. public static void AddForceAtPositionLocal(this Rigidbody body, Vector3 force, Vector3 position,
    3.             ForceMode forceMode = ForceMode.Force)
    4.         {
    5.             Quaternion rotation = body.transform.rotation;
    6.             body.AddForce(rotation * force, forceMode);
    7.             body.AddTorque(rotation * Vector3.Cross(position - body.centerOfMass, force), forceMode);
    8.         }
    9.