calc velocity on inclined plane with friction

Recommended Posts

Koga73    125
Hey, so in a 2d physics engine I have an inclined plane with a frictional value. Along with a "player" that has a mass. The player object will have an initial x and y velocity and hit an inclined plane that has a slope (theta) along with a friction coefficient. 1. How do I calculate the new speed using the initial speed, mass, gravity, friction coefficient of slope, and angle of slope for both the x and y directions over a period of time (delta). (This must work even if the slope is 0°) 2. How does acceleration factor in? You must accelerate down the slope, how is this calculated. Any help is appreciated! Thanks

Share on other sites
bzroom    647
What have you tried?

Side questions: what's the coefficient of restitution? can the object roll down the hill? Why do you assume the object will continue to slide down the hill and not come to a stop? how accurate of a friction model are you interested in? Are you familiar with vectors? is this a 2d side scroller or a 3d game?

Share on other sites
Koga73    125
Quote:
 what's the coefficient of restitution?

There isn't a coefficient of restitution. Only friction coefficient between the object and the surface

Quote:
 can the object roll down the hill?

no

Quote:
 Why do you assume the object will continue to slide down the hill and not come to a stop?

I do think that it will come to a stop. I'm hoping that when the object is on the slope it will already have an initial velocity vector. So I want to calculate the final velocity vector using the initial velocity when it hits the slope along with the friction coeffecient I have between the two objects, and of course theta.

Quote:
 how accurate of a friction model are you interested in?

Not super accurate. The physics engine itself is pretty basic. The objects all have acceleration and velocity vectors. Basic Bounding Box / Proximity collision models. I have the players working in game but they slide forever because there is no friction to stop them. I want to apply friction to my players on all surfaces, which could include slopes (defined by two x/y positions).

Quote:
 Are you familiar with vectors? is this a 2d side scroller or a 3d game?

2d side scroller

Share on other sites
bzroom    647
Constant deceleration:
void ApplyFriction( Vector& velocity, float rate ){  float speed = velocity.Length( );  if( speed == 0.0f ) return;  velocity /= speed;  rate = min( rate, speed );  speed -= rate;  velocity *= speed;}

Share on other sites
Koga73    125
Thanks for the suggestion but I'm not quite sure that is what I am looking for. I am looking for something more along the lines of a formula.

Such as (keep in mind I am making this up)
Vfx = Vix + (mg)(cos(theta)) * (frictionCoefficient)

Or something similar to that so I can calculate the new speed of the player based on the initial speed of the player and factor in the slope of the incline and the friction coefficient.

Share on other sites
bzroom    647
You should not be concerned with theta, cosine, or independent components. (ie x, y, z) You should treat everything as vectors and use vector operations such as dot product and cross product.

Why does my solution not achieve the results you desire? You'd also need to integrate the force from gravity projected onto the normal.

If you apply friction after the acceleration of gravity, it should be able to diminish any gravity acceleration rate less than the friction rate, bringing the object to a stop.

If the acceleration of gravity (after being projected onto the normal) is greater than the friction rate, then the object will continue to slide.

With constant accelerations there are only a few outcomes.

If accGravity == accFriction then velocity remains constant
if accGravity > accFriction then velocity increases continuously
if accGraivty < accFriction then velocity will diminish to zero.

So your three potential "final" velocities are: the same, infinity, and zero.

The rate that the velocity will change is (accGravity - accFriction).

[Edited by - bzroom on May 4, 2010 2:54:55 PM]

Share on other sites
Koga73    125
Hmm... the project is an actionscript project so I have written the engine myself. So far everything works with the exception of friction. I wrote a class called Vector2D that stores the x and y components of a vector and has math operations in it. So far with all of the math I am doing I am mostly working with the x and y components of the vector independtly. This is really the first physics engine I have written. It is for a college project.

Quote:
 You should not be concerned with theta, cosine, or independent components. (ie x, y, z) You should treat everything as vectors and use vector operations such as dot product and cross product.

How can I apply cross/dot product to the problem at hand?

Quote:
 You'd also need to integrate the force from gravity projected onto the normal.

How do I project the force of gravity (9.81 m/s) to the normal of the surface since gravity acts in the y direction?

Quote:
 If you apply friction after the acceleration of gravity, it should be able to diminish any gravity acceleration rate less than the friction rate, bringing the object to a stop.

Gravity has already been calculated into the speed of the player before the friction function will be called. To keep it simple for now, lets say the friction coefficient is .8. How could the amount of friction ever be greater than the amount of gravity? Am I comparing mg*frictionCoefficient to mg?

Like I've said so far I have been working with x/y components of my vectors. Is there a better solution? After re-examining the problem from a physics stand point I have realized that what I actually need to solve for is the new acceleration of the object, and then the acceleration values should slow the object down over time (unless the above ideas will work better)?

Share on other sites
bzroom    647
Calling apply gravity alone (assuming you're rectifying penetration) the body will ride along the surface, accelerating down hills, and decelerating as it goes up them.

Deceleration rate is not a coefficient. It's a rate, as in m/s^2. How ever you come up with this rate is up to you, may choose to use the normal force and a coefficient. But ultimately it's just going to result in some deceleration rate.

Vec3 ProjectOntoPlane( const Vec3& input, const Vec3& planeNormal ){	return input - planeNormal * Dot( input, planeNormal );}void ApplyGravity( Vec3& vel, const Vec3& surfaceNormal, float gravity, float deltaTime ){	Vec3 deltaV( 0, gravity * deltaTime, 0 );	vel += ProjectOntoPlane( deltaV, surfaceNormal );}void ApplyFriction( Vec3& vel, float friction, float deltaTime ){	float speed = vel.Length( );	if( speed == 0.0f ) return;	friction = min( friction * deltaTime, speed );	float newSpeed = speed - friction;	vel *= newSpeed / speed;	}void UpdateBody( Body& body, float deltaTime ){	const float gravityRate = -9.8f;	const float decelerationRate = 2.f;	Vec3 surfaceNormal = body.SittingOn( ).Normal;	ApplyGravity( body.Vel, surfaceNormal, gravityRate, deltaTime );	ApplyFriction( body.Vel, decelerationRate, deltaTime );	body.Pos += body.Vel * deltaTime;}

You can see here that the effective gravity rate is dependent on the dot product between gravity and the surface normal. The effective gravity rate will be zero if the surface is level. In that case the deceleration rate is significantly higher and will stop the object from moving.

Share on other sites
Koga73    125
wow great stuff! I think this is exactally what I was looking for. They don't teach it like that in physics lol. I really appriciate all the help! I'm gonna work on implementing some of it tomorrow I'll let you know how it goes.

Share on other sites
Koga73    125
So I got most of it working. The thing that I am not seeing with your example is mass. The deceleration due to friction should take into consideration the mass of the object. As in the real world it will take much longer for a semi truck to stop than a car. Any suggestions to how mass can be worked in to work with friction?

Share on other sites
bzroom    647
Mass is incorperated in the acceleration. If you talk about the acceleration of an object, its mass is not important. If two vehicles decelerate at 2m/s^s, regardless of their mass they are decelerating at the same rate (which means one has a lot better brakes than the other).

So basically you're confusing multiple topics. I semi truck takes longer to slow down because it applies a certain slow down force, not decleration. The deceleration would than be calculated with: A = f/m

I never mentioned forces, my example stays strictly on the 'A' side of the equation.

Another thing you may be poking at is that the friction force is often computed based on the normal force. Again, these are forces and not mentioned in the above discussion.

You would inversely scale the deceleration rate by the mass of the object.

Share on other sites
Koga73    125
Alright so I've really been struggling with getting the friction working over the past couple days. The problem I'm having is that the acceleration is half the max speed, so it will take half a second to reach max speed. That all works in a frictionless world... but as soon as I apply friction the friction value almost cancels out the acceleration so it takes FOREVER to reach max speed from a stationary position. On the same note, if I turn down the friction value then the player accelerates fine, but then slides and doesn't stop. I am having the hardest time finding a good mid-ground. Or perhaps I need a different approach.

My Friction Function (actionscript 3):

public static function applyFriction(toPawn:Pawn, overTime:Number):void {	if (!toPawn._onPhysical){		return;	}	if (toPawn._speed._MPS._x == 0){		return;	}		var tSpeedModifierX:int = toPawn._speed._MPS._x / Math.abs(toPawn._speed._MPS._x);	var tFrictionCoefficient:Number = toPawn._friction * toPawn._physicalBelow._friction;	var tFriction:Number = -(15) * tFrictionCoefficient;	var tDeceleration:Vector2D = new Vector2D((tFriction * tSpeedModifierX), 0);	applyAcceleration(toPawn, overTime, tDeceleration);				if ((toPawn._speed._MPS._x / Math.abs(toPawn._speed._MPS._x)) != tSpeedModifierX){		toPawn._speed._MPS._x = 0; //Check to see if we have gone past 0	}	toPawn._speed.calcMPS();}

Share on other sites
oliii    2196
Friction will determine your terminal velocity, which maybe lower than your expected max speed. If you take a car for example, it will take it a very long tine to reach max speed, which depends on the aerodynamics and engine power.

Frction is not easy tbh. There are all sorts of bodges applied to deal with ground friction and character physics, and usually it's not pretty.