Search Unity

Problem to to implement Hooke´s Law

Discussion in 'Physics' started by flatomic, Nov 9, 2016.

  1. flatomic

    flatomic

    Joined:
    Dec 9, 2013
    Posts:
    4
    Hi!

    I am trying to apply hooke's law to my box.
    The problem here is that this "car" not remains in the ground, it starts jumping.

    I set this values based on streetcars:



    Mass: 1000
    Suspension length: 1
    Stiffness: 8000



    This is my code:

    Code (CSharp):
    1.  void FixedUpdate()
    2.     {
    3.         RaycastHit hit;
    4.  
    5.         for (int i = 0; i < wheelPoints.Length; i++)
    6.         {
    7.             var wheelPoint = wheelPoints[i];
    8.  
    9.             if (Physics.Raycast(wheelPoint.transform.position,
    10.                                 -transform.up,
    11.                                 out hit,
    12.                                 suspensionLength,
    13.                                 layerMask))
    14.             {
    15.                 // Spring force
    16.                 float contactDepth = hit.distance - suspensionLength;  
    17.  
    18.                 float springForce = - stiffness * contactDepth;
    19.                
    20.                 // Final force or suspension force
    21.                 float suspensionForce = springForce;
    22.                
    23.                 rigidBody.AddForceAtPosition(transform.up * suspensionForce, wheelPoints[i].transform.position, ForceMode.Force);
    24.                 vehicleInAir = false;
    25.             }
    26.             else
    27.             {
    28.                 vehicleInAir = true;
    29.             }
    30.         }
    31.     }

     
  2. Hyblademin

    Hyblademin

    Joined:
    Oct 14, 2013
    Posts:
    725
    Is there drag force somewhere? Drag and inefficiency in the spring are what prevent real springs from endlessly oscillating.
     
  3. flatomic

    flatomic

    Joined:
    Dec 9, 2013
    Posts:
    4
    Nop, drag force is 0 and Angular Drag is 0.05.

    Sorry, the screenshot that I added before is very small.

     
  4. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,508
    Easy. You are simulating springs without damper. An ideal spring alone just keeps oscillating forever. What you have there is a Harmonic Oscillator.

    Real car suspensions have springs and dampers. Dampers are critical as they dissipate the oscillating energy in the spring allowing them to come to a rest pose. The damper can be implemented easily as a force that opposes the movement of the spring. Check out the mass–spring–damper example in the Wikipedia's Damping article.
     
  5. flatomic

    flatomic

    Joined:
    Dec 9, 2013
    Posts:
    4
    Before I added the damper force, the car has been crazy but it is even worse now. I don't know what am I doing wrong...



    Current values:
    Mass: 1000
    Suspension length: 1
    Stiffness: 8000
    damping: 800 // 10% of the stiffness

    Current code:

    Code (CSharp):
    1.  void FixedUpdate()
    2.     {
    3.         RaycastHit hit;
    4.         for (int i = 0; i < wheelPoints.Length; i++)
    5.         {
    6.             var wheelPoint = wheelPoints[i];
    7.             if (Physics.Raycast(wheelPoint.transform.position,
    8.                                 -transform.up,
    9.                                 out hit,
    10.                                 suspensionLength,
    11.                                 layerMask))
    12.             {
    13.                 // Spring force
    14.                 float contactDepth = hit.distance - suspensionLength;  
    15.                 float springForce = - stiffness * contactDepth;
    16.                
    17.                 //Damper force
    18.                 float compressionSpeed = contactDepth - lastContactDepth;
    19.                 float damperForce = - damping * compressionSpeed;
    20.              
    21.                 // Final force or suspension force
    22.                 float suspensionForce = springForce + damperForce;
    23.              
    24.                 rigidBody.AddForceAtPosition(transform.up * suspensionForce, wheelPoints[i].transform.position, ForceMode.Force);
    25.                
    26.                 vehicleInAir = false;
    27.                
    28.                 lastContactDepth = contactDepth;
    29.             }
    30.             else
    31.             {
    32.                 vehicleInAir = true;
    33.             }
    34.         }
     
  6. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,508
    1m is a large and unrealistic suspension.

    For Mass=1000, I have a vehicle where these suspension settings work rather good:

    Suspension length: 0.25
    Spring rate: 25000
    Damper rate: 1500​

    These are the settings at the WheelCollider. I'm not sure if/how they work implemented with direct forces.

    Also note that in your code vehicleInAir depends on the latest evaluated wheel only, regardless all other wheels.
     
    Last edited: Nov 18, 2016
  7. Meme_Dealler

    Meme_Dealler

    Joined:
    Aug 12, 2021
    Posts:
    1
    Just add wheels it works
     
  8. Maeslezo

    Maeslezo

    Joined:
    Jun 16, 2015
    Posts:
    331
    Damper force is damping coefficient * speed
    In your formula, I think compressionSpeed is not actually a speed, because you forgot dt
    Try
    Code (CSharp):
    1.                 float compressionSpeed = (contactDepth - lastContactDepth)/Time.deltaTime;
    2.                 float damperForce = - damping * compressionSpeed;