Car Suspension (Scripted)

Jailbreak Cars. I’ve been hearing a lot about them in the past few months and I’m really keen to get stuck into the mechanics of their suspension rig.

After doing my research, I have found out from numerous sources, that the rig uses Body Gyros & Body Thrusts in combination with ray-casting at each corner of the vehicle to acquire the force to push down on each wheel. This makes sense. The only part that doesn’t make sense is how this would relate to the servo movement of the wheels individually, allowing them to have their spring-like suspension; I could use a Spring Constraint but that defeats the purpose of the project.

I’m really keen to create my own version of the ‘Jailbreak Cars’ and I will be very much appreciative of all advice and examples posted.

31 Likes

The default Roblox jeep in the ‘Race’ and ‘City’ templates is a good starting point to show you how it works. I used the suspension code in that jeep as a base for this monstrosity:

It will require a fair bit of work for more advanced use, but it’s excellent as a starting point.

28 Likes

All this time it was right there in front of me. I really appreciate you showing me this. I’m going to read over it a lot. :slight_smile:

4 Likes

No problem! I forgot to add, for propulsion the default Roblox car script goes forwards and backwards by settings the velocity of the chassis rather than using a BodyThrust/Force - I wouldn’t recommend this as I’ve encountered bugs in the physics engine trying to use it.

10 Likes

Roblox default places being useful? Hoorah!

11 Likes

Having connected the wheels with the chassis, your equation for the spring becomes,
image
This could be extended further but it’ll be enough for our dampened spring.

local d = suspension_length

local a = 1.8 --Stiffness, higher means higher height at suspension
local b = 0.6 --Rigidity higher means the suspensions will get less effected by slight changes and will balance out unlike Roblox's suspensions. This is the part that dampens the suspension.

local ST = {dx=0,d2x=0} --For storing the derivatives per suspension

while loop do --For every suspension, in this case 4 of them
 local x = d - suspension_distance --X is how much the suspension is contracted

 local f = a*x + b*(x-ST.dx) + b/2*(x-ST.d2x) --Use the equation

 ST.d2x = ST.dx --Store the past values
 ST.dx = x
 
 Car.Force = Vector3.new(0,f,0) --Apply the forces
 Wheel.Force = Vector3.new(0,-f,0)
end

@gillern Is using this equation for his game. That car is his which I helped develop its math and physics.

27 Likes

Where does that equation come from, out of curiosity?

3 Likes

It’s following Newton’s Second Law of Motion, applied Hooke’s Law.

An obvious way to look at it is that, you want the force acting on the system as decelerating. This isn’t the exact form for the damped spring and it doesn’t have integration applied to it.

For F=-k*x, we can put our acceleration and velocity dependent equations directly in negative form to show that the force is mostly (dependent on our constant) opposite to that of acceleration and velocity.

It would’ve taken too much time to write the force that’d need to be applied.

But you can check this out for it:
http://www.ryanjuckett.com/programming/damped-springs/

8 Likes

I knew Hooke’s law, but I never actually knew you could solve for spring constants. (Useful information for a physics test next period…)

7 Likes

image
The jeep is really interesting without the body on it.

5 Likes

Why are you using a second derivative term? That’s accounted for by the inertia of the car, unless you have a mass-less car.

3 Likes

It says the second derivative in the formula but I’m actually using a 2*dt scale first derivative. This is to account for if the first derivation is not enough to slow it down, if it is, than 2*dt scale first derivative already equals to around 0.

If I wanted to do second derivative I’d need to change the script formula to

local f = a*x + b*(x-ST.dx) - b/2*(x-2*ST.dx+ST.d2x)

but that doesn’t work nicely. I didn’t actually mean to write second derivative to be honest. I was just lazy to show 2*dt in limit form.

Bear in mind that this is a fit equation.

6 Likes

Is this similar to how you made those hover cars @ Innovation inc?

Also, I’m understanding from the example Roblox made, that the following process is happening:

  • Body Gyro on chassis which keeps the vehicle wanting to be perfectly flat at all times
  • Body Thrust applied on all four corners of the vehicle to push it into the ground
  • Constant raycast from each corner to the ground to calculate the distance and to then be used to place each wheel aprox. half way between the two
  • This in combination with the body thrust and the body gyro generates the suspension

Have I understood this right? (This doesn’t seem right)

4 Likes

I’m also trying to achieve a similar vehicle system. I fail to understand how to keep the wheels in place and move the main chassis up and down based on the wheel distance from the ground.

3 Likes

That’s the point I’m stuck at.

1 Like

That’s exactly what I wrote.

I know, however that isn’t applied to the example made by roblox. I want to know how said example makes this particular part work.

Surely, if you move the wheel up using the weld cframe, the thruster would be pushing down and so it wouldn’t allow the wheel to move back down.

1 Like

Don’t use the one made by Roblox. You identified the purpose of the project as not using spring constraints and creating the spring simulation via a script.


Edit:

You’re not supposed to be CFraming anything. You’re going to use 4 attachments and 4 force constraints for the chasis. You’re going to use an attachment and force constraint for each wheel and connect the chasis and wheels using something like prismatic constraint.

You’re supposed to simulate the force of suspension on script and apply it via force objects.

3 Likes

The roblox example doesn’t use spring constraints. It’s purely code & body thrusters.

2 Likes

Ok… So what is it that you exactly want? Roblox’s example has a different approach to the equations than I do. UpdateThruster function in the LocalCarScript is the place where it does that.

--If we're on the ground, apply some forces to push the wheel up
bodyThrust.force = Vector3.new(0, ((stats.Height.Value - thrusterHeight)^2) * (force / stats.Height.Value^2), 0)
local thrusterDamping = thruster.CFrame:toObjectSpace(CFrame.new(thruster.Velocity + thruster.Position)).p * damping
bodyThrust.force = bodyThrust.force - Vector3.new(0, thrusterDamping.Y, 0)

but the one I suggested would have more realistic physics.

2 Likes