How to use formulas for car suspension

I’ve almost got my car suspension to work, however, i need help with one last thing,

I need to put mass into the current formula for the suspension, and since i suck at physics, im unsure how to do it:

function GetDist(part)
	local dir = part.CFrame.upVector * 100
	
	local ray = Ray.new(part.Position, Vector3.new(0,-150,0))
	local hit, pos = workspace:FindPartOnRayWithIgnoreList(ray, {Car}, false, true)	
	
	return (part.Position - pos).Magnitude
end

local d = 5

local a = 1.8 --Stiffness, higher means higher height at suspension
local b = .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

game:GetService("RunService").Stepped:Connect(function()
		for i, Wheel in pairs(Car.Wheels:GetChildren()) do
			local x = d - GetDist(Wheel) --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
		
			--print(f)
		
	 		Chassis.BodyThrust.Force = Vector3.new(0,f,0) --Apply the forces
			Wheel.BodyThrust.Force = Vector3.new(0,-f,0)
		end
end)
2 Likes

Can you highlight where you want the mass to be plugged into?

I want to plug it into this line: local f = (a*x + b*(x-ST.dx) + b/2*(x-ST.d2x)) --Use the equation

The chassis and (4) wheels have mass, i’ve tried already to do it and this is what i came up with:

local f = (a*x + b*(x-ST.dx) + b/2*(x-ST.d2x)) * (Chassis:GetMass() * workspace.Gravity)

This ends up glitching the car out though.

try “/” instead of “*”
so divide instead of multiply

so your code would be

local f = (a*x + b*(x-ST.dx) + b/2*(x-ST.d2x)) * (Chassis:GetMass() / workspace.Gravity)

That won’t work though, because even the following force is too weak:

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

And dividing it by gravity, will only make it weaker.

multiply the mass by 2 30charssssssssssssssssssssss

1 Like

What’s your intended behaviour here? Similarly, what glitches out? I don’t tend to use Roblox’s inherited :GetMass() method, instead I do something like:

local function getMass(part)
	-- this function calculates the mass of a singular part given its volume and the density as defined by the PhysicalProperties class
	local density = PhysicalProperties.new(part.Material).Density
	local size    = part.Size
	local volume  = size.x * size.y * size.x
	return density * volume
end

local function recurseMass(obj)
	-- this function recursively calculates a model's mass by finding all the parts and calling the 'getMass' function
	local mass = 0
	local recurse do
		function recurse(item)
			for i, v in next, item:GetChildren() do
				if v:IsA 'BasePart' then
					mass = mass + getMass(v)
				end
				recurse(v)
			end
		end
	end
	return mass
end

print(
	('More accurate mass of a Part is %d vs the :GetMass() method which thinks it\'s %d'):format(getMass(Instance.new 'Part'), Instance.new('Part'):GetMass())
)

-- "More accurate mass of a Part is 13 vs the :GetMass() method which thinks it's 6"
1 Like

It’s still too weak of a force:

https://gyazo.com/79ec4f28d07274377b1da0a285597799

At around * 20, if i lift the car off the ground, this happens: https://gyazo.com/11f3a68c2f8ad2f96bc5af803052cb5a

(This is how it glitches out @Isocortex)

I’ve tried the mass function you sent me and it does the same thing in the video, I don’t think it’s a problem with the mass, the suspension isn’t working.

Would it help if i supplied a place file, if so let me know

also, about your function, isn’t :GetMass() more accurate for meshparts, as that’s what im working with

Are you only getting the mass of the root part? You should probably be using the mass of the entire car, if not, throw in some magic numbers

That would be useful, I’ll do some testing for you as it’s hard to without knowing the architecture

1 Like

Here is the place file: CarWorking.rbxl (94.8 KB)
and here’s what im trying to achieve: https://i.gyazo.com/d2fa8bf90c02754c571a96bc11430d8d.mp4

Also, i’m only getting the chassis’ mass because the wheels’ density is very low 0.01, making their mass practically 0. and the wheels and chassis are the only non-massless parts.

try x10 30 charsssssssssssssssssssssssssssssss

I keep trying numbers, It doesn’t work, (30 chars)

to me the front wheels are fine its the back wheels that are the issue

All four of them are the exact same, except the wheels are a bit further the front of the car, which still should matter that much if the suspension is actually working

fixed it no longer bounces code

local DriveSeat = script.Parent

local function getMass(part)
	-- this function calculates the mass of a singular part given its volume and the density as defined by the PhysicalProperties class
	local density = PhysicalProperties.new(part.Material).Density
	local size    = part.Size
	local volume  = size.x * size.y * size.x
	return density * volume
end

local Car = script.Parent.Parent.Parent.Parent
local Chassis = Car.Body.Chassis
local Weight = getMass(Chassis) * workspace.Gravity

local Sounds = script.Parent.Parent.Parent.Parent.Sounds

local EngineSound = Sounds.Engine
local BasePlayback = 0.3

local Throttle = 1 / 15 + 1
local Ignore = Car:GetDescendants()

function GetDist(part)
	local dir = part.CFrame.upVector * 100
	
	local ray = Ray.new(part.Position, Vector3.new(0,-150,0))
	local hit, pos = workspace:FindPartOnRayWithIgnoreList(ray, {Car}, false, true)	
	
	return (part.Position - pos).Magnitude
end

local d = 5

local a = 1.8 --Stiffness, higher means higher height at suspension
local b = .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


game:GetService("RunService").Stepped:Connect(function()
		for i, Wheel in pairs(Car.Wheels:GetChildren()) do
			local x = d - GetDist(Wheel) --X is how much the suspension is contracted
	
	 		local f = (a*x + b*(x-ST.dx) + b/2*(x-ST.d2x)) * (Chassis:GetMass() * 17.57) --Use the equation
	
			ST.d2x = ST.dx --Store the past values
	 		ST.dx = x
		
			--print(f)
		
		 		Chassis.BodyThrust.Force = Vector3.new(0,f,0) --Apply the forces
		if Wheel.Name == "backW" then
			Wheel.BodyThrust.Force = Vector3.new(0,f,0)
		else
			Wheel.BodyThrust.Force = Vector3.new(0,-f,0)
		end
	end
end)

just re-name the back wheels to “backW”

Is this the kind of functionality you wanted?

I can’t tell what’s going on, is the suspension working?

I’ve supplied a video of how i want it to function, here it is again:https://i.gyazo.com/d2fa8bf90c02754c571a96bc11430d8d.mp4

1 Like

Just ran your code: https://gyazo.com/75c02eb5c16cbf1e23f667d1b37f3024

It shouldn’t work as all the wheels are orientated the same, the only reason in my demonstration the back came up first was because the center of balance is slightly further away from the rear wheels

Like this?