Search Unity

  1. Unity 2019.2 is now released.
    Dismiss Notice

Best way to implement the hydraulics and hydraulic stabilizers on a mobile crane

Discussion in 'Physics' started by B1PPER, Dec 23, 2014.

  1. B1PPER

    B1PPER

    Joined:
    Dec 22, 2014
    Posts:
    23
    Hi all,
    I'm trying to implement hydraulics and hydraulic stabilizers / outriggers in Unity using the physics engine. This would be like the feet that come down on a mobile crane to keep it from tipping over. The way this works in real life is the outrigger feet go down, make contact with the ground and by exerting force on the ground there's a responsive force (Newton's 3rd Law) that lifts the chassis up.. I've been messing around with this for a few days now... first tried just having a piston press against the ground, but apparently no responsive force is modeled into the engine. So, I tried adding a scripted responsive upward force applied to the horizontal portion of the stabilizer which kicked in when a collision between the outrigger pad and the ground (or a ground pad) occurred. This sort-of works, but getting the chassis back down and modelling when the pads should come up is now a concern. Plus, the code is getting a little convoluted because then there has to be a downward force applied when the stabilizer is raised, to take the upward pressure off the chassis. Is there's a more elegant solution that I'm overlooking? I've dug around on the forums and Answers, but there doesn't seem to be anything fitting this situation.

    The other part of this would be implementing the actual crane portion. I have part of that working except when the crane is elevated, or extended, the center of mass changes and thus the force required to manipulate the crane changes. I've looked at the various construction posts, but I didn't see anyone who's actually tried to model hydraulics. Any ideas on this as well?


    In the included picture, pretty much all of the primitives are rigidbodies. The cyilinder (chassis), stabilizer pad and the plate on the ground have box colliders. The horizontal is fixed-jointed to the chassis (eventually this would slide into the chassis), the vertical is connected to the horizontal by a configurable joint which only allows movement on the Y axis.
     

    Attached Files:

    Last edited: Dec 28, 2014
  2. Uberpete

    Uberpete

    Joined:
    Jan 16, 2014
    Posts:
    78
    A quick way to do this would to mess with the joints that come with the engine (perhaps spring?)

    The best way to do this would be to code it in. Is your current solution taking fluid dynamics into account or just relying on classical mechanics? You might want to calculate the actual pressure and forces with code and apply them to your objects. Depends on how accurate you want your simulation to be :p
     
  3. B1PPER

    B1PPER

    Joined:
    Dec 22, 2014
    Posts:
    23
    I guess when I said "modeled hydraulics" what I really meant was the behavior that an object having a force applied to it in a specific direction will "push away" from an unmovable object. Example, stand next to a wall, extend your arms toward the wall. You are exerting force on your arms in the direction of the wall, but when they reach the wall, you start pushing yourself away from the wall. That's what I mean, not fluid dynamics, etc...

    I realize it will need to be coded... and as I stated in my original post I have written code for it, but it's getting very convoluted. To the point to where I'm beginning to wonder, am I going about this all wrong. Let me try to be a little more specific about this. I'm not looking to go crazy with hydraulic pressure calculations, etc. The focus is on the crane movement itself. But, I want to use the built-in physics engine primarily because it would be a heck of a lot easier than re-inventing the wheel and coming up with algorithms to realistically mimic the movements the physics engine should already be able to provide.

    Imagine a crane with it's main arm structure connected to a pivot pin, which connects to a turntable. The sections of the crane arm are extendable (a telescoping boom). So here's a picture so there's no confusion as to what I'm talking about...



    At this point, I'm not worried about having visible hydraulic or cable actuators. The turntable can spin 360 degrees, the pivot pin allows the boom to elevate from 0 degrees to 75 or 80 degrees. Then you have two boom sections which can extend outward.

    Then there are the 4 outriggers/stabilizers which extend outward from the chassis. There is a separate piston that moves downward to make contact with the ground and apply force to the ground (which results in an upward force on the lateral arm).

    This video shows the movement of a single stabilizer



    I have code using the physics engine written which moves the outriggers in and out and the vertical piston up and down. (using AddForce()). If you watch the video, when the stabilizer pad makes contact with the ground, the force is then transferred upward to the lateral arm which lifts the lateral stabilizer and the truck chassis. That has been the tricky part. I'm new to the unity physics engine so I'm not real sure on the best way to code/model the reactive force which results when the pad contacts the ground. In effect the outrigger is still exerting a downward force, but since the ground is immobile, the result is the outrigger pushing itself away from the ground. That is what I'm having trouble coding. Because when the reverse happens, all of the weight has to be off of that stabilizer before it begins to retract off the ground. I've been experimenting with using collision detection to determine when the pad is in contact with the ground, but it doesn't seem to work very well. So I guess in this instance the real question is, if you want to simplify it, is can AddForce be used in such a way that when the object having the force applied to it will push away from an unmovable object. Or does AddForce essentially work only as a "thruster"?
     
  4. Uberpete

    Uberpete

    Joined:
    Jan 16, 2014
    Posts:
    78
    I'm afraid that AddForce is essentially a "thruster".
    If the masses of the bodies aren't to scale the simulation may act strangely too, perhaps you would want to check them out. The built-in physics engine is quite powerful and should be able to cope with such simulations with relative ease: I've used Unity for fluid simulations before :cool:

    If you can post your code and the setup/components of one of the stabilizers, I can take a look and give some suggestions.
     
  5. B1PPER

    B1PPER

    Joined:
    Dec 22, 2014
    Posts:
    23
    The weights aren't to scale, and I'm still playing with them. I think everything is set to 1 for mass. The set-up is pretty simple. Box in the middle (which is the body/chassis) is a rigidbody.

    Horizontal beam is a rigidbody, configurable joint permitting only X movement, connected to chassis.

    Vertical Beam is a rigidbody, configurable joint permitting only Y movement. Connected to the horizontal beam.

    There is a small plate which is unseen on the underside, outer part of the horizontal beam, just used to mark where to apply the upward force when the pad contacts the ground plate.
    outrigger pad, fixed joint to the vertical beam, also has the script attached because it's the object which is checked for collision with the ground plate.
    Then there's the ground plate which is just there to trigger the collision. I added that because I was getting sporadic detection with the terrain.

    Gravity is off for all rigidbodies.

    Code (CSharp):
    1.     private bool padGrounded = false;
    2.     private int modifier = 1;
    3.  
    4.  
    5.     // Use this for initialization
    6.     void Start () {
    7.             if (!leftSide) {
    8.                 modifier = -1;
    9.                 }
    10.     }
    11.     void OnCollisionEnter (Collision other) {
    12.         Debug.Log ("Pad Contact");
    13.         padGrounded = true;
    14.        
    15.         }
    16.  
    17.    
    18.  
    19.     void OnCollisionExit (Collision other) {
    20.         Debug.Log ("No Ground Contact");
    21.  
    22.         padGrounded = false;
    23.         }
    24.  
    25.  
    26.  
    27.     void FixedUpdate () {
    28.  
    29.         if (!padGrounded) {
    30.                         if (Input.GetKey (KeyCode.F)) {
    31.                                 horizontalPiston.rigidbody.AddForce (Vector3.left * Time.fixedDeltaTime * 100 * modifier);
    32.                         } else if (Input.GetKey (KeyCode.G)) {
    33.                                 horizontalPiston.rigidbody.AddForce (Vector3.right * Time.fixedDeltaTime * 100 * modifier);
    34.                         }
    35.                         if (Input.GetKey (KeyCode.T)) {
    36.                                 verticalPiston.rigidbody.AddForce (Vector3.up);
    37.                         } else if (Input.GetKey (KeyCode.B)) {
    38.                                 verticalPiston.rigidbody.AddForce (Vector3.down);
    39.  
    40.                         }
    41.                 } else {
    42.  
    43.             if (Input.GetKey (KeyCode.T)) {
    44.                 // T raises the stabilizer, but if the pad is in contact with the ground, force should be transferred to the
    45.                 // horizontal stabilizer to push the chassis upward (for levelling).
    46.            
    47.            
    48.                 horizontalPiston.rigidbody.AddForceAtPosition (Vector3.down * Time.fixedDeltaTime * 100, forcePlate.transform.position);
    49.            
    50.            
    51.            
    52.             } else if (Input.GetKey (KeyCode.B)) {
    53.                 horizontalPiston.rigidbody.AddForceAtPosition (Vector3.up * Time.fixedDeltaTime * 100, forcePlate.transform.position);
    54.             }
    55.  
    56.                 }
    57.  
    58.     }
    59. }
     
    Last edited: Dec 29, 2014
  6. Uberpete

    Uberpete

    Joined:
    Jan 16, 2014
    Posts:
    78
    I've made a quick attempt at modelling a bunch of stabilizers using joints, gravity and some sort of scale in terms of mass. It seems to work fine on my side, you can download it here. All you need to do is implement some side-ways movement, your collision detection (which works fine from the looks of it) and some fine-tuning like dynamic adjustment to terrain height (if you wish but this solution seems to work fine when tested on moderately bumpy surfaces).



    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Stabalizer : MonoBehaviour {
    5.  
    6.  
    7.  
    8.         //The controls
    9.  
    10.         public KeyCode Up = KeyCode.T;
    11.         public KeyCode Down = KeyCode.B;
    12.         public KeyCode Left = KeyCode.F;
    13.         public KeyCode Right = KeyCode.G;
    14.  
    15.  
    16.     public int maximumHeight = 30; //Maximum height for the horizontal piston
    17.     public float heightIncrements = 1.0f; //Increments in height
    18.     public float damping = 10.0f; // Damping in height increments
    19.  
    20.     public Rigidbody hPiston;  // Horizontal Piston
    21.  
    22.  
    23.     private ConfigurableJoint vPiston;  //Vertical Piston but we can get this from our horizontal piston
    24.     private float height;
    25.  
    26.     // Use this for initialization
    27.     void Start () {
    28.  
    29.     }
    30.  
    31.     // Update is called once per frame
    32.     void Update () {
    33.  
    34.         if (Input.GetKeyDown (Up) && height < maximumHeight) {
    35.  
    36.             vPiston = hPiston.GetComponent <ConfigurableJoint>();
    37.          
    38.             JointDrive d = new JointDrive();
    39.             height += heightIncrements;
    40.             d.positionSpring = height;
    41.             d.mode = JointDriveMode.Position;
    42.             d.positionDamper = 10;
    43.             d.maximumForce = 3.402823e+38f;
    44.          
    45.          
    46.             vPiston.yDrive = d; //so basically this uses the physics engine's built in joints!
    47.  
    48.         }
    49.  
    50.         else if (Input.GetKeyDown (Down) && height > 0)
    51.  
    52.         {
    53.  
    54.             vPiston = hPiston.GetComponent <ConfigurableJoint>();
    55.          
    56.             JointDrive d = new JointDrive();
    57.             height -= heightIncrements;
    58.             d.positionSpring = height;
    59.             d.mode = JointDriveMode.Position;
    60.             d.positionDamper = 10;
    61.             d.maximumForce = 3.402823e+38f;
    62.          
    63.          
    64.             vPiston.yDrive = d;
    65.  
    66.         }
    67.  
    68.         else if (Input.GetKeyDown (Left)){
    69.  
    70.             //TODO: ADD SOME SIDEWAYS MOVEMENT
    71.  
    72.         }
    73.  
    74.         else if (Input.GetKeyDown (Right)){
    75.  
    76.             //TODO: ADD SOME SIDEWAYS MOVEMENT
    77.  
    78.         }
    79.  
    80.  
    81.     }
    82. }
    83.  

    Hope this helps :)
     
  7. B1PPER

    B1PPER

    Joined:
    Dec 22, 2014
    Posts:
    23
    Hmmm... somethings not right because when the scene starts, the body and the stabilizers drop to the ground. Once there the stabilizers don't move at all. Is d.positionDamper supposed to resist gravity to keep the stabilizers up unless the spring force is acting on them?
    Oh, I see... it's a per tap increment.

    That's an interesting implementation... It does provide a nice even lift. However, the stabilizers will eventually be operated independently (or a couple at a time). So, when the one side goes up it actually produces a rotational force on the body. In effect if there's enough available lift on the one side you could actually tip the truck over. That isn't really possible here because the stabilizers float.

    I appreciate the assistance. I still don't fully understand joint drives, but this is helpful.
     
    Last edited: Dec 29, 2014
  8. Uberpete

    Uberpete

    Joined:
    Jan 16, 2014
    Posts:
    78
    You can achieve something like this (below) if you modify the stabilizer script (which would be friendlier than using multiple controls from a user POV). You may also want to add some joints to the pads to make them behave more natural.


    (the weird lines on the gif are from a horrible gif encoding algorithm, not the engine :p)

    Code (CSharp):
    1. public bool selected;
    2.  
    3.    
    4.     void Start () {
    5.  
    6.         selected = false;
    7.  
    8.     }
    9.  
    10.     // Update is called once per frame
    11.     void Update () {
    12.  
    13.         if (selected) {
    14.  
    15.             renderer.material.color = Color.red;
    16.  
    17.       //DO CRANEY STUFF
    18.  
    19.  
    20.         }
    21.  
    22.         else
    23.  
    24.         {
    25.  
    26.             renderer.material.color = Color.white;
    27.  
    28.         }
    29.  
    30.  
    31.     }
    32.  
    33.     void OnMouseDown (){
    34.  
    35.         selected = !selected;
    36.  
    37.     }
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Stabalizer : MonoBehaviour {
    5.  
    6.     public bool selected;
    7.  
    8.         //The controls
    9.  
    10.         public KeyCode Up = KeyCode.T;
    11.         public KeyCode Down = KeyCode.B;
    12.         public KeyCode Left = KeyCode.F;
    13.         public KeyCode Right = KeyCode.G;
    14.  
    15.  
    16.     public int maximumHeight = 30; //Maximum height for the horizontal piston
    17.     public float heightIncrements = 1.0f; //Increments in height
    18.     public float damping = 10.0f; // Damping in height increments
    19.  
    20.     public Rigidbody hPiston;  // Horizontal Piston
    21.  
    22.  
    23.     private ConfigurableJoint vPiston;  //Vertical Piston but we can get this from our horizontal piston
    24.     private float height;
    25.  
    26.     // Use this for initialization
    27.     void Start () {
    28.  
    29.         selected = false;
    30.  
    31.     }
    32.  
    33.     // Update is called once per frame
    34.     void Update () {
    35.  
    36.         if (selected) {
    37.  
    38.             renderer.material.color = Color.red;
    39.  
    40.             if (Input.GetKeyDown (Up) && height < maximumHeight) {
    41.              
    42.                 vPiston = hPiston.GetComponent <ConfigurableJoint>();
    43.              
    44.                 JointDrive d = new JointDrive();
    45.                 height += heightIncrements;
    46.                 d.positionSpring = height;
    47.                 d.mode = JointDriveMode.Position;
    48.                 d.positionDamper = 10;
    49.                 d.maximumForce = 3.402823e+38f;
    50.              
    51.              
    52.                 vPiston.yDrive = d; //so basically this uses the physics engine's built in joints!
    53.              
    54.             }
    55.          
    56.             else if (Input.GetKeyDown (Down) && height > 0)
    57.              
    58.             {
    59.              
    60.                 vPiston = hPiston.GetComponent <ConfigurableJoint>();
    61.              
    62.                 JointDrive d = new JointDrive();
    63.                 height -= heightIncrements;
    64.                 d.positionSpring = height;
    65.                 d.mode = JointDriveMode.Position;
    66.                 d.positionDamper = 10;
    67.                 d.maximumForce = 3.402823e+38f;
    68.              
    69.              
    70.                 vPiston.yDrive = d;
    71.              
    72.             }
    73.          
    74.             else if (Input.GetKeyDown (Left)){
    75.              
    76.                 //TODO: ADD SOME SIDEWAYS MOVEMENT
    77.              
    78.             }
    79.          
    80.             else if (Input.GetKeyDown (Right)){
    81.              
    82.                 //TODO: ADD SOME SIDEWAYS MOVEMENT
    83.              
    84.             }
    85.  
    86.  
    87.         }
    88.  
    89.         else
    90.  
    91.         {
    92.  
    93.             renderer.material.color = Color.white;
    94.  
    95.         }
    96.  
    97.  
    98.     }
    99.  
    100.     void OnMouseDown (){
    101.  
    102.         selected = !selected;
    103.  
    104.     }
    105.  
    106.  
    107.  
    108. }
    109.  
     
  9. B1PPER

    B1PPER

    Joined:
    Dec 22, 2014
    Posts:
    23
    The gifs aren't showing up for me so I'm not sure what you're describing here. What I gather from the code is that when a stabilizer is selected the parts are tinted red... that's a good idea.

    The keyboard control is just temporary. In the end it'll probably be something like you go to one side of the crane and one analog stick controls one stabilizer, the other controls the second. Then you can switch to the other side... once they're set you go up in the cab, etc... I'm more concerned with getting the actual operations to work because all of this will have to be integrated into a 3D model which will be built later (by someone else because I don't have much 3D experience).
     
  10. Uberpete

    Uberpete

    Joined:
    Jan 16, 2014
    Posts:
    78
    Firstly, here's the gif! https://drive.google.com/file/d/0B3rZeKUDjp8iUjFDa1V5QW1MS28/view?usp=sharing It worked earlier, something must be up with Unity's servers :(

    So you're trying to make something more like this?


    For the horizontal movement, I'd allow movement on the x-axis for a configurable joint (between the body and stabilizers) by setting it to limited or even free. Then just add some x movement code to the stabilizer script and all should be fine.
    When you get a proper model, be sure to get it modular (ie. each part separately) otherwise it would be very difficult to work with.
     
  11. B1PPER

    B1PPER

    Joined:
    Dec 22, 2014
    Posts:
    23
    No, no, no... I said crane... not train. :) Yes, I was thinking about about doing the look-to-select a control because this will be Rift enabled. Once the control was selected, the analog sticks would do the actual movement which means I also have to factor in the analog axis position and have that affect the speed of the stabilizer movement.

    Yes in your GIFs, that is what it's supposed to do as far as rolling the body. Now, using your implementation, how do you start with the stabilizers off the ground? What I was trying to do earlier was increase the Y scale of the body so it would be in contact with the ground (in reality the wheels would be in contact), but I can't seem to get the outriggers to come up off the ground.

    I'm trying to make an outrigger setup that can be used on cranes, fire trucks, etc...

    This is pretty much the end-result I'm looking for...
    Here's a couple of crane outriggers:



     
    Last edited: Jan 15, 2015
  12. Uberpete

    Uberpete

    Joined:
    Jan 16, 2014
    Posts:
    78
    Well, from the top of my head, you should be able to simply change the connection points of the stabilizer-to-body joints, raising and lowering the stabilizers. For the inward/outward movement you could mess with the joints' x-movement, otherwise just scale the horizontal beam and move the vertical beam accordingly (I'm on my phone so code WILL NOT WORK :eek:).

    In regards to the rear-wheel pickup, the script in my last post already allows such behaviour, just select the back stabilizers.
     
  13. B1PPER

    B1PPER

    Joined:
    Dec 22, 2014
    Posts:
    23
    vBeam is what needs to move up and down, not the BeamH... so changing the stabilizer to body point won't produce the desired effect. The Horizontal Beam's connection point on the body is fixed... the Vertical Beam has to move up and down when the outriggers aren't in contact with the ground. In my initial diagram I may have oversimplified a bit... because the horizontal bars aren't climbing the verticals. When the pads are in contact with the ground, the relative effect of the horizontals climbing the vertical beams may be fine.
     
  14. Uberpete

    Uberpete

    Joined:
    Jan 16, 2014
    Posts:
    78
    Ah, yes :D I've modified the script a bit to just add a "locked" feature (a bool that's true as the stabilizers are being deployed). It should work fine... All that's needed is some horizontal deployment :p

    Here's a package: "Crane 2" and here's a gif (it takes some time to load)
    (Press z to deploy the stabilizers)


    Code (CSharp):
    1. //  declarations and blah
    2. private bool locked; //Locks the joints in position
    3.  
    4. // Use this for initialization
    5. void Start () {
    6.    
    7.     locked = true;
    8.    
    9. }
    10.  
    11. // Update is called once per frame
    12. void Update () {
    13.    
    14.    
    15.     if (selected) {
    16.        
    17.        
    18.         if (Input.GetKeyDown (Unlock)){
    19.            
    20.             locked = !locked;
    21.            
    22.         }
    23.  
    24.        
    25.        
    26.     }
    27.    
    28.     else
    29.        
    30.     {
    31.        
    32.         renderer.material.color = Color.white;
    33.        
    34.     }
    35.    
    36.     if (locked)
    37.        
    38.     {
    39.        
    40.        
    41.        
    42.         rigidbody.AddForce (Vector3.up * 10);
    43.        
    44.         vPiston = hPiston.GetComponent <ConfigurableJoint>();
    45.        
    46.         JointDrive d = new JointDrive();
    47.         height = 0;
    48.         d.positionSpring = height;
    49.         d.mode = JointDriveMode.Position;
    50.         d.positionDamper = 0;
    51.         d.maximumForce = 3.402823e+38f;
    52.        
    53.        
    54.         vPiston.yDrive = d;
    55.        
    56.     }
    57.    
    58.    
    59. }
    60.  
    61. void OnMouseDown (){
    62.    
    63.     selected = !selected;
    64.    
    65. }
    66.  
    67.  
    68.  
    69. }
    70.  

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class Stabalizer : MonoBehaviour {
    5.  
    6.     public bool selected;
    7.  
    8.         //The controls
    9.  
    10.         public KeyCode Up = KeyCode.T;
    11.         public KeyCode Down = KeyCode.B;
    12.         public KeyCode Left = KeyCode.F;
    13.         public KeyCode Right = KeyCode.G;
    14.         public KeyCode Unlock = KeyCode.Z;
    15.  
    16.  
    17.  
    18.     public int maximumHeight = 30; //Maximum height for the horizontal piston
    19.     public float heightIncrements = 1.0f; //Increments in height
    20.     public float damping = 10.0f; // Damping in height increments
    21.  
    22.     public Rigidbody hPiston;  // Horizontal Piston
    23.  
    24.  
    25.     private ConfigurableJoint vPiston;  //Vertical Piston but we can get this from our horizontal piston
    26.     private float height;
    27.     private bool locked; //Locks the joints in position
    28.  
    29.     // Use this for initialization
    30.     void Start () {
    31.    
    32.         selected = false;
    33.         locked = true;
    34.  
    35.     }
    36.    
    37.     // Update is called once per frame
    38.     void Update () {
    39.    
    40.  
    41.         if (selected) {
    42.  
    43.             renderer.material.color = Color.red;
    44.  
    45.             if (Input.GetKeyDown (Unlock)){
    46.  
    47.                 locked = !locked;
    48.  
    49.             }
    50.  
    51.  
    52.  
    53.             if (Input.GetKeyDown (Up) && height < maximumHeight) {
    54.                
    55.                 vPiston = hPiston.GetComponent <ConfigurableJoint>();
    56.                
    57.                 JointDrive d = new JointDrive();
    58.                 height += heightIncrements;
    59.                 d.positionSpring = height;
    60.                 d.mode = JointDriveMode.Position;
    61.                 d.positionDamper = 10;
    62.                 d.maximumForce = 3.402823e+38f;
    63.                
    64.                
    65.                 vPiston.yDrive = d; //so basically this uses the physics engine's built in joints!
    66.                
    67.             }
    68.            
    69.             else if (Input.GetKeyDown (Down) && height > 0)
    70.                
    71.             {
    72.                
    73.                 vPiston = hPiston.GetComponent <ConfigurableJoint>();
    74.                
    75.                 JointDrive d = new JointDrive();
    76.                 height -= heightIncrements;
    77.                 d.positionSpring = height;
    78.                 d.mode = JointDriveMode.Position;
    79.                 d.positionDamper = 10;
    80.                 d.maximumForce = 3.402823e+38f;
    81.                
    82.                
    83.                 vPiston.yDrive = d;
    84.                
    85.             }
    86.            
    87.             else if (Input.GetKeyDown (Left)){
    88.                
    89.                 //TODO: ADD SOME SIDEWAYS MOVEMENT
    90.                
    91.             }
    92.            
    93.             else if (Input.GetKeyDown (Right)){
    94.                
    95.                 //TODO: ADD SOME SIDEWAYS MOVEMENT
    96.                
    97.             }
    98.  
    99.  
    100.  
    101.        
    102.  
    103.             }
    104.  
    105.         else
    106.  
    107.         {
    108.  
    109.                 renderer.material.color = Color.white;
    110.  
    111.         }
    112.  
    113.         if (locked)
    114.  
    115.         {
    116.  
    117.        
    118.    
    119.             rigidbody.AddForce (Vector3.up * 10);
    120.  
    121.             vPiston = hPiston.GetComponent <ConfigurableJoint>();
    122.            
    123.             JointDrive d = new JointDrive();
    124.             height = 0;
    125.             d.positionSpring = height;
    126.             d.mode = JointDriveMode.Position;
    127.             d.positionDamper = 0;
    128.             d.maximumForce = 3.402823e+38f;
    129.            
    130.            
    131.             vPiston.yDrive = d;
    132.  
    133.         }
    134.  
    135.  
    136.     }
    137.  
    138.     void OnMouseDown (){
    139.  
    140.         selected = !selected;
    141.  
    142.     }
    143.  
    144.  
    145.  
    146. }
    147.  
     
  15. B1PPER

    B1PPER

    Joined:
    Dec 22, 2014
    Posts:
    23
    I had an epiphany last night so I actually have it working pretty well. I had to go back to using AddForce because i just couldn't get the joint drive method to work. I added in a hydraulic lock as well, I will have to see if it functions like yours. I also made a separate script for the pads which handles the collision detection. When the collider is hit, as before it applies an upward force... But, now, each hydraulic assembly is a two part system... a piston and a hydraulic cylinder. So now the upward force is applied to the cylinder, not the horizontal. I'm also trying to make the the class itself as generic as I can... So instead of having a single class that controls both horizontal and vertical, each stabilizer gets its own script attached and the public parameters are changed appropriately. The other sticking point was figuring out when to switch back to moving the piston instead of applying force to the cylinder. So in order to get the pad to come off the ground I had to store the local position of the vertical piston when it first makes contact with the collider. When you are lowering the chassis the piston passes that location by just enough to trigger a detection conditional.
     
    Last edited: Dec 30, 2014
  16. Uberpete

    Uberpete

    Joined:
    Jan 16, 2014
    Posts:
    78
    Sounds good! In terms of collision, you may want to take a look using raycasts: storing the local position and then waiting for a collision would be very risky and open to all sorts of glitches.
    I still think that simulating the fluid as a spring is more realistic: it has a nice and more natural bounce to it which isn't really achievable with AddForce. The script I wrote works on a per-stabilizer basis and moves the vertical piston (in the last post I was referring to the inny-outy movement moving the horizontal ones, not the up-down movement).
     
  17. B1PPER

    B1PPER

    Joined:
    Dec 22, 2014
    Posts:
    23
    I'm still struggling with the understanding and implementation of the spring method... that's what's keeping me from using it, not that I think AddForce is better. I will probably end up switching to the joint drive as soon as I have a better understanding of how it works. Conceptually I think I understand it. The hydraulic lock I was using used the freeze position which of course locks up everything, so it doesn't work if you try to do independent stabilizer movement. So what I think I'm going to try is using the joint drive to hold the piston in place and see if working on that furthers my understanding of joint drive to the point to where I can switch the main movement over from AddForce. No offense, but I don't really like to cut-and-paste code if I don't have a pretty good understanding of what's going on. Then I'll take a look at raycasts... I haven't done anything with them before either. Unity is after-all new to me. Again, thanks for all the input and assistance.
     
  18. Uberpete

    Uberpete

    Joined:
    Jan 16, 2014
    Posts:
    78
    Have you checked the documentation?

    I like to think of the spring method like this

    I agree with the no cut-and-paste ethos; Unity is very easy to pick up so don't worry :)
     
  19. B1PPER

    B1PPER

    Joined:
    Dec 22, 2014
    Posts:
    23
    Yes, I looked at the docs for joint drive... as I said, conceptually I understand it. What is throwing me is that you aren't using targetPosition in your code. In that case, where does targetPosition default to? Your code changes the positionSpring to achieve movement. I think that's the part I'm not getting.

    In order for this to be usable as a hydraulic lock, I would have to set the targetPositon to the piston/cylinder's location when the lock comes on and set the positionSpring to a very high number to overcome gravity exerted on the piston as well as the weight of any attached rigidbodies... allowing virtually no pull on the rubber band. Then to unlock it, just set JointDriveMode to none. Or am I mistaken as to how jointdrive works?
     
  20. Uberpete

    Uberpete

    Joined:
    Jan 16, 2014
    Posts:
    78
    TargetPosition is, as a default, set to where the joints start at.
    I wasn't using it and was just relying on the springs to keep stuff in place. When activating the hydraulic lock the springs become redundant (they're set to 0) allowing the joint to slide freely. Then, AddForce is used to keep the pistons in place until the hydraulic lock is turned off and the springs are reactivated.
     
  21. B1PPER

    B1PPER

    Joined:
    Dec 22, 2014
    Posts:
    23
    Okay, but where in relation to the object the joint is a component of is TargetPosition located or defaulted to? Is it the anchor? The parent transform.localposition?

    Also when I quickly tried the hydraulic lock on your model, when the lock is engaged, the legs pop up. When it's released, the legs drop. When I'm referring to the hydraulics being locked I mean no fluid is flowing so there should be no movement. So in my code I had the lock turning on whenever a control isn't being used. The movements are all continuous motion, as long as the control is activated the piston moves. I started with code to simply resist the gravity on the piston pulling it down, but when there is other weight on it, the piston drifts.

    Before I could use joint drive I would have to alter it so it moves continuously instead of stepping with each key press.
     
  22. B1PPER

    B1PPER

    Joined:
    Dec 22, 2014
    Posts:
    23
    I've come up with another way to lock-out motion on the hydraulics... creating a FixedJoint which overrides the ConfigurableJoint. Then when the hydraulics get the command to move again the joint is destroyed. Tried it, seems to work just fine, but it's affecting the pad lift code, so the pads come up immediately instead of coming up when they should. So, I'm going to look into raycast and see if I can figure out how I would use that.

    EDIT: yes, ray cast looks like it will work nicely. I'm going to do a raycast up from the ground pad through the piston (which doesn't have a collider) to the cylinder and store that distance when the collider on the pad is hit. Then when retracting it will check the distance between the cylinder and the pad. As soon as the distance is shorter than the stored distance, we switch over to piston movement only. The modular way I am going to make this class you could theoretically put a collider on the outside of a horizontal piston and if it connects with an immovable object it pushes the horizontal piston away from that object.
     
    Last edited: Dec 30, 2014
  23. Jean-Fabre

    Jean-Fabre

    Joined:
    Sep 6, 2007
    Posts:
    344
    Hi,

    Indeed, I switching to a fixedJoint will be very stable. I am guessing you pad logic is getting fixed by now right?

    You mentionned my excavator in your pm, but I think here you don't need to go all out on a custom solution for stablity, especiall since you moved to a fixed joint ( which is not how I did it, but would be how I would if I had to redo it)

    Bye,

    Jean
     
  24. B1PPER

    B1PPER

    Joined:
    Dec 22, 2014
    Posts:
    23
    Well, I had the pad logic working... the only problem is going to the fixed joint and using raycast for measuring deployment distance instead of marking the local position seemed to introduce some oddities as well as made the stops very bouncy. So when the pad made contact with the ground it "bounced" Sometimes causing the raycast to get an inaccurate value. One of the two also broke the way the chassis settles... The pads will be up but the body slowly rocks back down as if it's still cushioned so I ended up scrapping that changed code and I'm going to try it again with just the fixed joint and leave the raycast out and see how it goes.

    Did you destroy your configurable joint then re-instantiate it for movement or did you just add the fixed joint and destroy it when necessary for movement?
     
    Last edited: Jan 3, 2015
  25. Jean-Fabre

    Jean-Fabre

    Joined:
    Sep 6, 2007
    Posts:
    344
    Hi,

    You should not need raycasting to do this joint, and you should also look into stiffening your physics simulation, the bounciness could be actually coming from the physics engine itself.

    -- yes, destroy the config joint and add a fixed joint everytime, that's the most straight forward way and since this is a granular action, the performance hit is not going to be an issue at all.

    Bye,

    Jean
     
  26. Uberpete

    Uberpete

    Joined:
    Jan 16, 2014
    Posts:
    78
    I forgot about this thread XD How's the simulation going?
     
  27. B1PPER

    B1PPER

    Joined:
    Dec 22, 2014
    Posts:
    23
    Well the outriggers work for the most part. I implemented the hydraulic locks, movement is pretty good, bouncing has gone away. The chassis settles properly most of the time. The chassis settling problems had to do with the drag values for various components so those had to be zeroed (or 1'ed) out when they weren't in motion. I am still having issues with the pads "sticking" to the ground occasionally. That's likely due to the pads moving around when other outriggers move the chassis. I've been working on attaching wheels with realistic suspension movement and experimenting with applying the code to actual 3D models instead of just using it on some ProBuilder primitives. The recent snag I've run into is that I need to bump up the mass of the various components (which also means upping the force multipliers) so the boom portion will interact appropriately with overhead obstructions like power lines (the sim is meant to train for safety as well as build skill). It worked pretty well with the masses all zeroed out, but using the larger masses makes the movement more erratic and certain portions of the models separate unexpectedly. I still would also like to more effectively model the Center of Gravity shift so low angle loading can create problems.
     
  28. Uberpete

    Uberpete

    Joined:
    Jan 16, 2014
    Posts:
    78
    With extra mass, you need to update the joints as well. Have you done that?
     
  29. B1PPER

    B1PPER

    Joined:
    Dec 22, 2014
    Posts:
    23
    I'm not sure what you mean by updating the joints. They're set to Infinity for break force. Actually I spoke too soon, looks like the bouncing is still there on closer examination. Regardless of where the bounciness is coming from, I need to find some way of dampening it some. I had actually been working on a different portion of the sim so I hadn't looked at the outrigger code for while.
     
  30. Uberpete

    Uberpete

    Joined:
    Jan 16, 2014
    Posts:
    78
    Hmmm. Are you still using my approach with the joints? What's your current setup?
     
  31. B1PPER

    B1PPER

    Joined:
    Dec 22, 2014
    Posts:
    23
    I had to go back to AddForce because when I started running into other issues, I didn't really understand joint motor enough to overcome those issues. I was also struggling with how to get the controls to work with Joint Motor since it seems to be position-based. So when the extend or retract controls were activated the outrigger would overshoot since the user has no way of knowing what position they are selecting.

    The current setup is a two part hydraulic system (a piston and a cylinder) linked by a configurable joint. The axis and direction is set in the parameters for the script. As long as the pad or tip of the piston isn't in contact with an object the piston moves in and out using AddForce. When the pad makes contact with an object force is also added to the cylinder in the opposite direction the piston is moving. I'm adding a Fixed Joint anytime the system isn't moving and destroying it for movement. I thought about adding code to figure out if the object it was contacting is movable or not, but for my purposes the vertical piston should always be contacting the ground. If I decide I want to add in crushing parked cars or something silly like that, I'll revisit the issue. Right now there's a multiplier on the reverse force for the cylinder because lifting the chassis requires more force than moving the piston (obviously). I was thinking that if I add more drag to the piston and increase the force that I may be able to get rid of that multiplier and further simplify the system. I think some of the bounce is due to insufficient drag on the cylinder.
     
  32. Uberpete

    Uberpete

    Joined:
    Jan 16, 2014
    Posts:
    78
    Calculating to adjust the drag would have to be done in real-time. This could be costly so if you're simulation doesn't need to be that detailed, miss it out. (I'm thinking of induced drag btw just in case you're saying something totally different)
     
  33. B1PPER

    B1PPER

    Joined:
    Dec 22, 2014
    Posts:
    23
    I wasn't really planning on calculating anything... The drag value I'm changing is the rigidbody drag value. I'd just be changing it between constants, since I have no idea how I would calculate an appropriate value.