Search Unity

Question Getting acceleration is glitchy

Discussion in 'Physics' started by tmcthee, Mar 16, 2023.

  1. tmcthee

    tmcthee

    Joined:
    Mar 8, 2013
    Posts:
    119
    Hi,

    I'm sure this is going to be something dumb, but...
    I'm trying to get the acceleration of a rigid body using the following code.

    Code (CSharp):
    1. localVelocity = _transform.InverseTransformDirection(_rigidBody.velocity);
    2. GetAcceleration();
    3.  
    4. private void GetAcceleration()
    5. {
    6.     acceleration = ((localVelocity - oldVelocity) * Time.fixedDeltaTime)*1000.40f ;
    7.     oldVelocity = localVelocity;
    8. }
    The object it's getting the data from is accelerating smoothly at about -0.13 but the numbers I'm getting glitch as sometimes 0 and sometimes -0.25.

    Code (CSharp):
    1. (0.02, 0.00, -0.13)acceleration
    2.  
    3. (0.02, 0.00, -0.13)acceleration
    4.  
    5. (0.02, 0.00, -0.13)acceleration
    6.  
    7. (0.02, 0.00, -0.13)acceleration
    8.  
    9. (0.02, 0.00, -0.12)acceleration
    10.  
    11. (0.00, 0.00, 0.00)acceleration
    12.  
    13. (0.03, 0.00, -0.25)acceleration
    14.  
    15. (0.00, 0.00, 0.00)acceleration
    16.  
    17. (0.03, 0.00, -0.24)acceleration
    18.  
    19. (0.01, 0.00, -0.12)acceleration
    20.  
    21. (0.01, 0.00, -0.12)acceleration
    22.  
    23. (0.01, 0.00, -0.11)acceleration
    24.  
    25. (0.01, 0.00, -0.11)acceleration
    26.  
    27.  
    28.  
    I think it must be calling the method twice in some frames and skipping some other frames.
    I'm not sure how to get it to work.
    I've tried calling GetAcceleration() in Update and FixedUpdate. I've tried multiplying and dividing by Time.deltaTime and Time.fixedDeltaTime but nothing seems to work.

    I expected calling it in fixedUpdate would work, but no.

    Any ideas?
    Thanks in advance.
     
  2. leebissessar5

    leebissessar5

    Joined:
    Nov 15, 2022
    Posts:
    48
    The derivative method is noisy, so I created a method that worked well for my purposes. I had a thread earlier on that here.

    The gist of it is that you back calculate it by calculating Coriolis and centrifugal forces. You then solve for acceleration given that as well as the forces you applied earlier in code. In your case, you don't have to deal with a mass matrix, so you divide each component in the result by the mass to get the actual acceleration.
     
    Last edited: Mar 18, 2023
  3. lightbug14

    lightbug14

    Joined:
    Feb 3, 2018
    Posts:
    447
    1000.40?

    It makes sense since the method updates your oldVelocity value each time you call it.
    An alternative to that is to calculate acceleration from one physics frame to the next:
    Code (CSharp):
    1. public class GetAccelerationScript : MonoBehaviour
    2. {
    3.     Rigidbody _rb;
    4.     Vector3 _oldLocalVelocity;
    5.  
    6.     Vector3 _acceleration;
    7.     public Vector3 GetAcceleration() => _acceleration;
    8.  
    9.     private void Awake()
    10.     {
    11.         _rb = GetComponent<Rigidbody>();
    12.         StartCoroutine(PostSimulationCoroutine());
    13.     }
    14.  
    15.     IEnumerator PostSimulationCoroutine()  //<--- Runs after OnCollisionXXX/OnTriggerXXX
    16.     {
    17.         YieldInstruction waitForFixedUpdate = new WaitForFixedUpdate();
    18.         while (true)
    19.         {
    20.             yield return waitForFixedUpdate;
    21.  
    22.             var localVelocity = transform.InverseTransformDirection(_rb.velocity);
    23.             _acceleration = ((localVelocity - _oldLocalVelocity) * Time.fixedDeltaTime);
    24.             _oldLocalVelocity= localVelocity;
    25.         }
    26.     }
    27. }