I’m working on a raycast vehicle for a cool little project. That being said, I have to simulate friction. A simple friction model I have found is normal force * constant clamped to the max friction force. simple enough, only problem is that since normal force is constant (mass * gravity), how would this work? it would have to be relative to the slide amount in some way but I am unsure how to do this. It’s also very possible that im doing everything wrong. Thanks in advance!
Normal force isnt necessarily just mass * gravity
It also has to do with other downward forces caused by different things
As youre driving around, the main thing is the torque caused by acceleration or deceleration which acts downwards on the wheels and therefore affects the normal force and friction
Some formulas
p = m v
Δp = F Δt (or F = Δp/Δt)
T = F L
p is momentum, m mass v velocity
Δp is change in momentum, F force and Δt change in time
T is torque, F force and L is the distance the torque is applied at
I believe the torque is caused by the difference in the center of mass of the wheels and car and just the car
You obviously dont have wheels so you could just estimate this distance and mess with it to see what works best for you
Ill call this distance L1
To get the “instantaneous” force, I would poll the velocity every x seconds, the time between polls now being your Δt value
To calculate Δp, calculate the momentum of the last poll and of the current poll and subtract them:
Δp = (m * vcurrent) - (m * vprevious)
You can then plug this into the formula to get the force, F=Δp/Δt
F = m(vcurrent- vprevious)/Δt (this is both the change in momentum formula and F=ma which is a kind of derivation of both which is cool)
Then put it through one torque for the vertical difference in center of masses
T = F * L1
Then put it through the next torque based on the wheels distance from the center of mass along the force vector which can be calculated with some fancy math
(wheelPos-centerOfMassPos):Dot(acceleration.Unit)
Where acceleration is calculated as (vcurrent- vprevious)/Δt
So the final thing, combining all of this would be
Every x seconds, poll the velocity and calculate these things:
a = (vcurrent - vprevious)/Δt
(vcurr is the current velocity, vprev is the velocity last poll, Δt is time between polls)
F = m * a
T1 = F * L1
(L1 is the distance between the center of mass of the car AND wheels, and just the car, you can use this to scale up or down the force manually since you dont have wheels)
T2 = T1 * (wheelPos-centerOfMassPos):Dot(a.Unit)
T2 is the final force acting on each wheel, so youll have to recalculate just T2 for each wheel
Make sure you just add this onto the force of gravity too (like T2+mg)
I havent tested this and dont expect it to work first try, so please post any problems and the related details or just confusions here cause this isnt the best written thing in the world
Oh wow! That’s a lot. Thank you so much for writing all of it. I’ll try it later today and let you know if I have any issues.
so every part I understand until T2. should the
be the same as the L1 used in T1?
Sorry if this is a dumb question btw.
L1 is the vertical difference between the center of mass of the tires + car and just the car
wheelPos-centerOfMassPos is the distance between the center of mass of the whole car and each wheel
Hopefully that makes it make a bit more sense
Ok thank you, last questions before I attempt to implement this and yes, its probably another dumb one. Unfortunately, I’m not good at physics so I apologize that you have to deal with me. How do you calculate center of mass? I was assuming it was just the main mass part of the car’s position or something. Is this force in world space or local space? I was assuming its world cause nothing indicates it would be local.
Btw, ill go ahead and mark your answer as a solution since it has been very helpful.
To get the center of mass of the car just use part.AssemblyCenterOfMass, or just really any position you think works best
As for L1 I think you should just choose different values until it feels right
Also yes the velocities, accelerations, forces, positions, centers of mass, etc are all world space
Ok so this is what I came up with which causes my car to fling out of the map. I know Im doing something wrong but I’m unsure what since this is all new to me. I tried different L1 values and it didnt really matter. Thank you so much for your help by the way:
local function Friction(dt)
for i,v in pairs(Wheels:GetChildren()) do
local Thruster = v.Thruster
local Friction = Thruster.Frictionn
local a = (Thruster.Velocity - (lastV[Thruster] or Vector3.new()))/dt
local F = GetMass() * a
local T = F * 0.5
local T2 = T * ((v.Grounded.Value and v.Grounded.ContactPoint.Value or Vector3.new()) - Base.AssemblyCenterOfMass):Dot(a.Unit)
if v.Grounded.Value then
Friction.Force = Thruster.CFrame:VectorToObjectSpace(T2)
else
Friction.Force = Vector3.new()
end
lastV[Thruster] = Thruster.Velocity
end
end
When calculating T2 try using the thrusters position or something that will always have a reliable position
I think the problem is that youre doing vector3.new() on the t2 line (its fine in the other line though), which makes the game thing the wheel is positioned at the center of the world and could make a massive force
If that doesnt work Id print out T2 to see what its doing
Also make sure you account for gravity
Would I just multiply T2 by gravity? Also I fixed that line and printed T2 and it seems like the force is really high on the x axis.
Edit: Matter of fact, its really high on all axis
I would personally just use the magnitude of the force and apply it backwards, the direction of t2 should always be downwards which should then be translated into backwards friction force
Once you do that you can just subtract mass * gravity from T2s magnitude
Also how high is it?
Can you tell where anything starts getting high in the math/where the problem originates?
It happens as soon as I hop in the vehicle so its kind of hard to tell. it seems to be with the fact that before you get in the vehicle, its laying on the ground, but then the spring force acts on it and causes the velocity to change.
I mean more in the code, sorry for not specifying
Like, for example, “the dt value is very low which causes a very large acceleration value”
I would trace the high number back until its no longer high or you see the problem
Alright. I’ll do that. If I do apply the magnitude in the backwards direction though, how would that help with the x axis sliding?
Thats a good point, I would just apply it opposite to the unit velocity (probably fixed to be parallel to the car) in that case
So like
-velocity.Unit * T2.Magnitude * frictionConstant
I would get the local space velocity and get rid of the y value and use that
(Actually that would kinda be useless in this case, I would apply it opposite to the inertial “force” caused by stopping and turning and accelerating
This gets into some fairly complex math so Ill get back to you on that one)
It doesn’t work as of right now. Ill attempt more tomorrow. Thank you so much for helping me! I really appreciate it!