Changes between Initial Version and Version 1 of TheStabilizerBars


Ignore:
Timestamp:
2011-09-17 13:17:39 (13 years ago)
Author:
edy
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • TheStabilizerBars

    v1 v1  
     1{{{ #!Markdown 
     2 
     3## The stabilizer bars: creating physically real, stable vehicles 
     4 
     5Unity exposes the nVidia PhysX engine for physics. The WheelCollider object allows to easily model vehicles. But there's a problem you will surely encounter the first time you start experiencing with WheelColliders: 
     6 
     7__Q: Why my absolutely simple car (rigidbody + 4 wheel colliders) flips over so easily when steering?   
     8A: Because that's exactly how such car would behave in real life!!__ 
     9 
     10So you have created a box, added a rigidbody and four wheel colliders. Perhaps you've even used some real car's data (mass, dimensions...). You have added a control script, tested it, and as soon as you gain a bit of speed and do a corner, the car rolls and flips over. 
     11 
     12If you could build that in real life, it would do the same! PhysX is not perfect, but resembles the physical behavior of real objects in a fairly good manner. 
     13 
     14Also note that the default WheelCollider's friction curve parameters in Unity (1,20000,2,10000,1) define _a tyre with almost infinite grip_. So the rigidbody has no choice but rolling-over when steering even at low speed. You should first set the last parameter (_Stiffness_ Factor) to 0.01-0.03 to have more realistic tyres. However you would get either a too sliding car or a car that rolls over when steering at low speeds. 
     15 
     16 
     17__Q: But real cars don't roll over so easily. Why?   
     18A: Because real cars have STABILIZER BARS (aka anti-roll or anti-sway bars)__ 
     19 
     20[http://auto.howstuffworks.com/question432.htm][1] 
     21 
     22>_Think about what happens to a car in a sharp turn. [...] the part of the car on the outside of the turn gets pushed down toward the road and the part of the car on the inside of the turn rises up. In other words, the body of the car "rolls" 10 or 20 or 30 degrees toward the outside of the turn. If you take a turn fast enough, the tires on the inside of the turn actually rise off the road and the car flips over._ 
     23 
     24Sounds familiar?   
     25Stabilizer bars "link" the two wheels of the same axle allowing a limited degree of freedom between them. When one of the wheels is pushed upwards, the stabilizer bar transfers a portion of that compression force to the other wheel, so its suspension compress as well. This limits the roll of the body's car at that axle. 
     26 
     27>___If you don't have a stabilizer bar, you tend to have a lot of trouble with body roll in a turn___. _If you have too much stabilizer bar, you tend to lose independence between the suspension members on both sides of the car._ 
     28 
     29 
     30__Q: I haven't heard of such bars! Are really so important?   
     31A: Absolutely. Stabilizer bars are an essential part of a vehicle's suspension system in the same way as springs and dampers are.__ 
     32 
     33Look under your car, observe the suspension behind the drive wheels. You'll be able to easily identify a rigid bar that travels from one wheel's suspension to another. That's it. Some exceptions are a few car models that use dynamic systems (ej. computer-controlled hydraulic systems) to actively emulate the behavior of the anti-roll bars in turns. 
     34 
     35IMHO, an AntiRoll script for WheelColliders should be consideered a standard resource, and should be mentioned in Unity / PhysX documentation and tutorials as a basic requirement for physically real vehicles. Actually, anti-roll bars are barely mentioned in the last chapter of the [Unity's Car Tutorial][2], where an alternate car physics model is proposed. 
     36 
     37 
     38__Q: What about all other solutions proposed over Unity and PhysX forums? (lower center of mass, angular drag, custom friction models...)   
     39A: The essential requirements for having a car that physically feels like real include the anti-roll bars.__ 
     40 
     41Once you have the REAL absolutely simple car (rigidbody + four wheel colliders + 2 anti-roll bars) you can then apply all other techniques to get special behaviors on your car and/or tweaking its handling, i.e for arcade-style driving. 
     42 
     43Even with this simple car you'll find a lot of options to tweak and play with, all of them affecting the handling and feel of the car: mass, REAL center of mass (typically moved towards the engine location), front-rear springs, front-rear dampers (must be different because the axle under the engine will support more weight), front-rear anti-roll bar stiffness... 
     44 
     45No need for complicated custom friction/drag models at the beginning - leave them for final tweaks if necessary. You'll see how much the handling can change by simply adjusting the difference between the stiffness of the front and rear stabilizer bars. 
     46 
     47 
     48__Q: What's bad with lowering the center of mass?   
     49A: Jumps, collisions, crashes or air-tricks will look weird because of the false center of mass.__ 
     50 
     51Artificially lowering the center of mass is just a workaround that works under some circumstances, but fails at others. Having the REAL center of mass in the car, and making it stable by means of stabilizer bars, will make almost all situations behave like real. 
     52 
     53 
     54__Q: I've run your demo and the red pickup truck still flips over!   
     55A: Look at that kind of car. If you do a close turn at moderate speed with that car in real, surely you'd roll over as well!__ 
     56 
     57If you are (like me) used to watch those "educative" documentaries at Discovery Channel "Road Rampage", "Destroyed in Seconds", and so on, you'll know how easily this kind of cars can roll over at relatively normal speeds. Also, you may have heard about "The moose test", which is a heavy "S" turn test performed at 80 Km/h (50 mph). Many actual cars failed that test (Google for "the moose test" or see [the Moose Test at Wikipedia][3]) 
     58 
     59Note that in the [live demo][] the elevation of the center of mass is around the middle of the car's body! The anti-roll bars are doing an excellent work already. Press 5 four times for disabling them (last setting button shows _none_) and you'll see the difference. 
     60 
     61![Center of Mass][10] 
     62 
     63__Q: How to simulate stabilizer bars in Unity / PhysX?   
     64A: Easily ;)__ 
     65 
     66Anti-roll bars work by transferring some compression force from one spring to the opposite in the same axle. The amount of the transfered force depends on the difference in the suspension travel among the wheels. 
     67 
     68So first task is to calculate the suspension travel on each wheel, as well as determine whether is grounded or not. We want the travel value to be between 0.0 (fully compressed) and 1.0 (fully extended): 
     69 
     70        groundedL = WheelL.GetGroundHit(hit);  
     71        if (groundedL)  
     72           travelL = (-WheelL.transform.InverseTransformPoint(hit.point).y - WheelL.radius) 
     73                                  / WheelL.suspensionDistance;  
     74        else  
     75           travelL = 1.0; 
     76 
     77We multiply the travel diference by the AntiRoll value, which is the maximum force that the anti-roll bar can transfer among the springs (we could call this the Anti-roll bar's stiffness). This yields the amount of force that will be transfered: 
     78 
     79        var antiRollForce = (travelL - travelR) * AntiRoll; 
     80 
     81Finally, we must simply substract the force from one spring and add it to the other. We achieve this by adding opposite forces to the rigidbody at the positions of the WheelColliders: 
     82 
     83        if (groundedL)  
     84                rigidbody.AddForceAtPosition(transform.up * -antiRollForce, WheelL.transform.position);               
     85        if (groundedR)  
     86                rigidbody.AddForceAtPosition(transform.up * antiRollForce, WheelR.transform.position); 
     87 
     88 
     89__Q: What's a good AntiRoll value? Which units is it expressed in?   
     90A: A good value is roughly the value of the wheel's spring. Both are expressed in Newtons.__ 
     91 
     92The spring value means the force the spring can give when fully compressed, and the AntiRoll value means the amount of force that can be transfered from one spring to another. Having the same values for Springs and AntiRoll in the same axle means that the anti-roll bar can transfer up the entire force of one spring to the other. 
     93 
     94 
     95__Q: Can I have the Unity script for an anti-roll bar?   
     96A: Sure, here is it.__ 
     97 
     98Add two anti-roll scripts to your vehicle, one per axle (front - rear). Set the left-right wheels on each one and adjust the AntiRoll value. Remember to set the center of mass at the real position. 
     99 
     100The full script: AntiRollBar.js 
     101 
     102        var WheelL : WheelCollider;  
     103        var WheelR : WheelCollider;  
     104        var AntiRoll = 5000.0;  
     105 
     106        function FixedUpdate ()  
     107                {  
     108                var hit : WheelHit;  
     109                var travelL = 1.0;  
     110                var travelR = 1.0; 
     111 
     112                var groundedL = WheelL.GetGroundHit(hit);        
     113                if (groundedL)  
     114                        travelL = (-WheelL.transform.InverseTransformPoint(hit.point).y - WheelL.radius)  
     115                                          / WheelL.suspensionDistance; 
     116                                   
     117                var groundedR = WheelR.GetGroundHit(hit);  
     118                if (groundedR)  
     119                        travelR = (-WheelR.transform.InverseTransformPoint(hit.point).y - WheelR.radius)  
     120                                          / WheelR.suspensionDistance; 
     121                                           
     122                var antiRollForce = (travelL - travelR) * AntiRoll; 
     123                 
     124                if (groundedL)  
     125                        rigidbody.AddForceAtPosition(WheelL.transform.up * -antiRollForce, WheelL.transform.position);  
     126                if (groundedR)  
     127                        rigidbody.AddForceAtPosition(WheelR.transform.up * antiRollForce, WheelR.transform.position);  
     128                } 
     129 
     130__Q: How can I set a real center of mass for my vehicle?   
     131A: Use non-overlapping colliders to roughly resemble your vehicle's shape, then move the center a bit down and towards the position of the engine.__ 
     132 
     133![Colliders and Center of Mass][11] 
     134 
     135Unity/PhysX calculates the center of mass based on the position and volume of the GameObject's colliders. Note that overlapping colliders add more mass at the overlap position. 
     136 
     137Typically, you would only need to move the center of mass a bit down (as effect of the chassis' mass) and towards the position of the engine (front - rear). For instance, if your vehicle has front engine and its front is oriented in the Z+ direction, you should only need to move the (automatically calculated) center of mass a bit down and 1 meter to the front: 
     138 
     139        function Start ()  
     140                {  
     141                rigidbody.centerOfMass += Vector3(0, -0.20, 1.0);  
     142                } 
     143 
     144__Q: Does it really works so good? Could it really be so simple??   
     145A: See it by yourself, try the [live demo][].__ 
     146 
     147You can have a good view of how it works by pressing V (secondary camera), then pressing 5 while driving for setting the stabilize bar's stiffness. The bars are disabled when the last setting button shows _"none"_. Press Enter to restart the car after flipping over. The default _"AUTO"_ mode changes the stiffness depending on the speed.  
     148 
     149 
     150__Q: Is there any drawback?   
     151A: As the force is applied externally to the wheel, it causes some side effects on the grip.__ 
     152 
     153In a turn, the script applies an external force to lift the rigidbody at the outside wheel. This means that the vertical force at that wheel is reduced, so its grip is reduced as well. If the car gets stuck over an obstacle where one wheel is in the air and the other at the ground, then the grounded wheel will be pushed upwards at the full anti-roll bar's force. That wheel will have very little friction over the ground, even being the only one grounded at that axle. 
     154 
     155Ideally the anti-roll bar's force should be added to the wheel's spring force, but we don't have access to the WheelCollider's internals. Also, changing the the spring value at run-time has either no effect or cause secondary unwanted effects. 
     156 
     157Two possible workarounds I can think of: 
     158 
     159- Implementing the anti-roll bars with joints, so they sum the appropiate force to the wheel. However, changing wheel's position at runtime is NOT recommended as the WheelCollider pre-calculates some data on start based on its distance to the center of mass. Changing the WheelCollider's Center property is safe though. 
     160- Automatically adjusting the anti-roll force acording to the speed of the vehicle, so lower speeds reduce or disable the effect of the anti-roll bars. This is the solution implemented in the [live demo][]. 
     161 
     162 
     163 
     164 
     165 
     166 
     167 
     168[1]: http://auto.howstuffworks.com/question432.htm 
     169[2]: http://unity3d.com/support/resources/tutorials/car-tutorial 
     170[3]: http://en.wikipedia.org/wiki/Moose_test 
     171 
     172 
     173[10]: http://www.edy.es/unity/Offroader/Offroader-CenterOfMass.jpg 
     174[11]: http://www.edy.es/unity/Offroader/Offroader-Boxcolliders.jpg 
     175 
     176[live demo]: http://www.edy.es/unity/offroader.html 
     177 
     178}}}