How do i make my suspension formula work?

I have made a very simple demo to try help me understand suspensions etc.
I’m trying to regulate the suspension based on how far it is from the ground (The further it is from the ground, the less the force, allowing it to drop down ; The closer to the ground, the more the force, allowing it to go up) and i’m not too sure how to apply it.

This is what i have now:

local Weight = script.Parent.Load:GetMass() * workspace.Gravity
local Thruster = script.Parent.Thruster
local Thrust = script.Parent.Thruster.BodyThrust

local Height = script.Parent.Wheel.Size.Y
local MaxDist = Height * 1.5

local RS = game:GetService("RunService")

local Dampening = 0.2

function GetDist()
	local Origin = Thruster.Position
	local Rayn = Ray.new(Origin, Thruster.CFrame.UpVector * -150)
	
	local hit, pos = workspace:FindPartOnRayWithIgnoreList(Rayn, script.Parent:GetChildren())
	
	return (Origin - pos).Magnitude or Height
end

local CurrentTime = tick()

RS.Stepped:Connect(function()
	
	local k = Weight * (tick() - CurrentTime)
	
	local f = k * (Height - GetDist()) * Dampening
 
	Thrust.Force = Vector3.new(0,f,0)
	print(f)
	
	
end)

(EDIT: Changed the script)

This happens when i run the script:

https://gyazo.com/792e3eb064c0a77fbc8a0876aaf2a025

Sorry if this is really easy, as this is my first time dealing with this, i’ve got no clue how to do it. Thanks in advance

2 Likes

Is there any reason you don’t want to use constraints?

Maybe lower this, but it won’t solve it.

Try to use math.clamp to set a min and max value the suspension could be.

Yes, they’re really buggy.and i’ve found the best cars with suspension dont use constraints

The problem is that the wrong things are being plugged into the formula, i just need help with plugging in the right values and including a variable for the mass of the car

1 Like

This may the problem then, if your thing is going down infinitely. I noticed the output showed a growing number, meaning f is always increasing?

Instead, calculate the current force, and set the body mover force as a simple lerp between the last and new.

You can get a free lerp function by putting this somewhere in your code: local lerp = CFrame.new().lerp. It says it doesn’t exist, but it definitely does.

…That’s not what im trying to do though, I don’t need to lerp, it’s already smooth, I just need to plug in values, and i don’t know how to include mass and whatever else i’m missing into the equation.

Before you include mass, you have to fix what’s already here.
Your lerping is causing issues, because it’s taking the previous values in the incorrect context and continuing to increase those previous values.

I know it’s a problem with what’s already there, that’s what this post is for, It’s not a problem with the stored derivatives, it’s a problem with the ones i’ve included, I’m posting this, to ask how i should fill in the equation.

1 Like

Maybe have a variable for the mass, maybe using like part:GetMass()?

Using that variable, you can change how fast/slow the suspension rises back up, using a cube root of the mass.

It’s right here, I’ve tried already, I’ve researched as much as i could fathom, I just need help from someone who can plug in the values for me and explain why

What constants do you need help with? You have two constants, a and b. Value a is your spring constant. This determines how much force is generated proportional to how ‘stretched’ the spring is. Use this to make your spring more responsive. Your value b is the dampening term. This term creates a force that resists the speed of a spring moving, as well as the rate of change of the speed. Use this to make your spring resist movement.

1 Like

Im stuck on the distance part, In the original formula. Two undefined variables exist:


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

Suspension Length and Suspension Distance, im not too sure how to fill them in, i’ve tried my best in my script but i just dont fully understand those two variables

Maybe it would be good to incorporate RenderStepped.
https://developer.roblox.com/en-us/api-reference/event/RunService/RenderStepped

Also, maybe this will help.

1 Like

I’ve incorporated stepped as renderstepped doesn’t work for server, I’ve also incorporated the equation you’ve sent, It works i think, it just needs to be dampened and it gets stronger the more time elapses, is the time meant to reset every oscillation?

local Weight = script.Parent.Load:GetMass() * workspace.Gravity
local Thruster = script.Parent.Thruster
local Thrust = script.Parent.Thruster.BodyThrust

local Height = script.Parent.Wheel.Size.Y
local MaxDist = Height * 1.5

local RS = game:GetService("RunService")

local Dampening = 0.2

function GetDist()
	local Origin = Thruster.Position
	local Rayn = Ray.new(Origin, Thruster.CFrame.UpVector * -150)
	
	local hit, pos = workspace:FindPartOnRayWithIgnoreList(Rayn, script.Parent:GetChildren())
	
	return (Origin - pos).Magnitude or Height
end

local CurrentTime = tick()

RS.Stepped:Connect(function()
	
	local k = Weight * (tick() - CurrentTime)
	
	local f = k * (Height - GetDist()) * Dampening
 
	Thrust.Force = Vector3.new(0,f,0)
	print(f)
	
	
end)

This is what it looks like: https://gyazo.com/792e3eb064c0a77fbc8a0876aaf2a025

(Btw this is great progress for me, Thank you so much for showing me that equation :slightly_smiling_face:)

Alright, here is some more more math you can read up on. Remember that you don’t need to completely understand it as long as you are able to use the equation. I also had a hard time reading it. Dampening is one of the topics.

https://photos.app.goo.gl/9PP25x1Rw4VMbG6r9

1 Like

I’m really not good with equations lol, I’ve come up with a different way of doing it though. Using BodyPositions and thrusts, Just one obstacle to tackle.

How can i lower the thrust as it reaches the desired height?

RS.Stepped:Connect(function()
	local pos = GetDist(Load)
	
	BP.Position = Vector3.new(Load.Position.X, pos.Y + TargetDistance + Load.Size.Y / 2, Load.Position.Z)
	--BG.CFrame = CFrame.new(0,0,0)
	
	for i, v in pairs(Thrusters) do
		local __, Distance = GetDist(v)
		
		local Difference = TargetDistance - Distance
		
		v.BodyThrust.Force = Vector3.new(0,math.clamp(Difference * ForceToApply, -Weight / 100, Weight / 100),0)
		print(Difference * ForceToApply)
	end
end)

The Difference simply is just in factor form how far it is from the ground, if it’s at the desired level, the value is 0, If it’s 2 studs above the desired 4 the value is 0.5 etc.

Then the ForceToApply is just how much force should be applied on the thrusts
https://gyazo.com/3a72da9275ac15611ec387a5e2034251

Overtime it bobs way more, it’s not entirely grounded, how can i fix this?

If you don’t want to get into the maths (and I don’t want to either…), I would say you should just use a BodyPosition, use raycasting to set the part to always be 2 studs (or whatever) above the ground, and use the dampening feature that’s already built in.

1 Like

I am using bodyposition for the main body so it can stay constantly above ground, then im using bodythrusts at each wheel to simulate suspension and to tilt the car, so i can’t do without them, i’ll try research up on some stuff though.

Thank you for everything up til now, you’ve been (the only) great help!

Maybe you could use BodyPositions for each wheel and get rid of the center force you have.

There is a simple dampening equation in the pictures I sent which may help you.

Also, note that with certain equations, oscillation continues forever, but it keeps getting smaller and smaller. Watch out for that, perhaps that could or could not cause the bobbing you mentioned