Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Voting for the Unity Awards are OPEN! We’re looking to celebrate creators across games, industry, film, and many more categories. Cast your vote now for all categories
    Dismiss Notice
  3. Dismiss Notice

Clutch Lockup Logic State

Discussion in 'Physics' started by NDSno1, Feb 15, 2018.

  1. NDSno1

    NDSno1

    Joined:
    Dec 20, 2014
    Posts:
    223
    Hi fellow game devs,
    I'm not sure if this should be in "Scripting" or "Physics" section, but since it relates to physic so I'm putting it here for now, mod please move it if necessary.
    With the help of @Edy and others in my previous posts about clutch modeling, I now have a solid direction for the modeling the clutch. The way I'm doing it is having 2 clutch states: locked and unlocked. EngineRPM and torque will be calculated separately in each state. My problem right now is the logic and code for specifying locking and unlocking.

    The condition for locking is when (engineSpeed - drivetrainSpeed) in previous update cross zero (different sign) with the current update (to determine if engineSpeed = drivetrainSpeed or not in-between updates) and engineTorque <= clutchTorque.

    The condition for unlocking is when engineTorque > clutchTorque.

    The diagram looks roughly like this (taken from matlab website with the similar implementation):

    However, the 2 conditions are triggers for switching states, not for determine the current state to be in, so in the end my clutch state just jumped around. I don't have a lot of experience in doing state machine, so can some one give me rough code of how to implement this? Below is my rough code:
    Code (CSharp):
    1. speedError = engineSpeed - drivetrainSpeed;
    2. if ((Math.Sign(speedError) != Math.Sign(deltaW) && currentTotalEngineTorque <= clutchReactTorque))
    3.                 {
    4.                     clutchLocked = true;
    5.                 }
    6.                 else clutchLocked = false;
    7.  
    8. deltaW = speedError;
    9.  
    10. //end of update
    I think the main struggle is the cross zero. Because cross zero is the "trigger condition" to check if the clutch should lock when it is slipping, not the condition for continuous locking, while the code I have above is the "continuous condition" saying "this condition is true then it is locked/unlocked" every update. Another word, if the clutch is slipping, the condition above would decide if it's locked or not, but once it is locked, the cross zero condition is not true anymore (since speedError and deltaW have same sign as engineSpeed == drivetrainSpeed when clutch is locked). I'm sorry that I cannot explain this better as English is not my first language. Can some one please give me some directions?
     
  2. Hyblademin

    Hyblademin

    Joined:
    Oct 14, 2013
    Posts:
    725
    A typical implementation of a state machine is something like this:

    Code (CSharp):
    1. //Pseudocode
    2.  
    3. int state; //Could be an Enum
    4.  
    5. //Perform state transitions if conditions are met
    6.  
    7. if (state == 0)
    8. {
    9.     if ([transition0to1])
    10.     {
    11.         state = 1
    12.     }
    13.     else if ([transition0to2])
    14.     {
    15.         state = 2
    16.     }
    17. }
    18. else if (state == 1)
    19. {
    20.     //Similar to above
    21. }
    22. else if (state == 2)
    23. {
    24.     //Similar to above
    25. }
    26.  
    27. //Execute state "outputs"
    28. //Separated from above state checks for formatting and execution order
    29.  
    30. if (state == 0)
    31. {
    32.     //Do state 0 stuff
    33. }
    34. else if (state == 1)
    35. {
    36.     //Do state 1 stuff
    37. }
    38. else if (state == 2)
    39. {
    40.     //Do state 2 stuff
    41. }
    There are various ways to format this, but I like the above example. You can specify self-transition conditions and invalid states if you want, which would be transitioned to in the case that no defined transition states are met. This can help with debugging, but requires recovery conditions. I usually don't do this.

    In your case, you could define a state variable that represents lock or slip states, and use a simple structure like this one to change the state variable. Then, the actual values are calculated one way if the state is lock, and the other way if it's slip.

    I also just want to make sure that you're calculating max clutch torque based on clutch position. You probably are, but I didn't see it mentioned so I though I could throw that out there.
     
  3. NDSno1

    NDSno1

    Joined:
    Dec 20, 2014
    Posts:
    223
    Thanks for the reply. I applied your implementation and it is working very well now, still need to test further for any bug.

    Yes I have that, clutchTorque = clutchInput * clutchCapacity.