The simplest method of applying surface friction?

Started by
19 comments, last by rumblesushi 13 years, 4 months ago
dangerDave, thanks for your suggestion. Right now the friction that is implemented is ultra simple air drag, and I'm looking to implement angular friction alongside this, but I'll look into your method.

Taz - thanks for your reply, that's pretty much what I tried to do actually. Logically, it seems like the best/simplest method doesn't it?

The collision response diverts the velocity along the polygon's surface, and right now, it behaves as if the wheels are balls.

So the first thing I thought of was to simply rotate the new diverted velocity vector according to the wheel's direction. Logically this seems to the absolute simplest way to implement surface/side friction, without having to complicate my simple, arcadey handling/physics.

But annoyingly, I just couldn't get it working.

Do you know of any source code that features this method?

If not, could you point me in the right direction of how to apply these new projections? I generally like to do things myself from scratch, but I tried something similar to what you describe, and there was obviously something I wasn't doing correctly.

My collision response manipulates a new position point, then the new velocity is simply velocity = newPos - startPos, and position = newPos. Pretty straightforward, and like Emergent said, it seems like this angular friction should be applied AFTER this collision response, after the gravity has done it's thing etc.

Cheers.

[Edited by - rumblesushi on December 4, 2010 5:01:09 PM]
Advertisement
Are you having trouble calculating the direction vectors? The car's 'up' vector is typically the normal to the plane the car is on (possibly an average of surface normals for uneven surfaces). Perpendicular to this is the drive shaft which is the car's 'forward' vector, and a side vector, perpendicular to both. The car wheels turn in the worldspace plane formed by the forward and side vectors. When the wheels are straight, their normals are equal to the side vectors. The wheels steer by rotating in this plane. i.e. they rotate around the car's up vector. For example, if you turn the steering wheel far enough to produce a turn of 20 degrees, you can determine the wheel normal vector by rotating the car's side vector 20 degrees around the car up vector. Cross product the car's up vector and the wheel's normal vector to find the wheel's forward vector.
Then you can project the force vector onto the wheel normal/forward vectors and apply separate friction terms for each.
Quote:Original post by rumblesushi
What about the "n" after the dot products? What does that mean?


It's a vector. It's the car's "sideways" vector. Originally I wrote "the car's left vector is 'n.'" That equation projects off any component of the force in the sideways direction.

("n" might have been a bad choice of variable name. Other people will probably use that for the surface normal. I was thinking of it as the normal to a velocity constraint...)

Quote:Original post by taz0010
you can project this vector onto the direction the wheels are facing, and also onto the vector perpendicular to the direction the wheels are facing. Then you apply separate friction modifiers to each vector.


Taz and I are suggesting very similar things.

Quote:Original post by taz0010
Are you having trouble calculating the direction vectors?


Yeah, that's what it sounds like.

To elaborate on what Taz wrote: Ordinarily, you keep a set of vectors around that describes the orientation of the car. One points forward. One points left (or right). One points up. All as Taz described.

You may also know these vectors as the columns of the rotation matrix describing the car's orientation; that's what they are.

You might want to try drawing the various force vectors in your simulation, including the projected one. If you can see everything that's happening I think you'll get what's going on.
Hey Emergent, oh I know what N is. What I mean is, how is the N after the projection part of the equation? Because the projection of the vector F onto the axis N, is simply the dot product divided by N squared right? With it producing a value between 0 and 1 if they are parallel along that axis.

I'm pretty sure it's nothing to do with miscalculating the orientation vectors, because like you say, I store them and use them when rotating my matrices.

I store them as the x, y and z axis of each object, with the xAxis being the column 11, 21, 31, y being 12, 22, 23, and z being 12, 23, and 33.

The car orients to the terrain according to the wheels, and that all works fine.

So Taz and Emergent I think it must simply be how I was trying to rotate the velocity or applying the projected force/friction that was wrong.

I'll try again now.

By the way, yep, good idea, I'll render the forces.

[Edited by - rumblesushi on December 5, 2010 3:53:46 PM]
Quote:Because the projection of the vector F onto the axis N, is simply the dot product divided by N squared right?


The scalar projection of F onto N is d = F.N / sqrt(N.N). Or more simply, the dot product of F and a normalised N. Idealy the vector you're projecting onto is already normalised so you only need to do the dot product.
d can be negative depending on the direction of the vectors, and friction force always opposes the direction of motion. Make sure you're handling this so friction never causes the car to move faster.
Hey Taz, what I was trying before was slightly different, but I have this working now in it's most basic form, using the side component of the car, I haven't done the front wheels yet.

Oh and in Emergent's equation, the N afterwards means multiplied by normalised N right?

That's what I got working yesterday, but as it happens I'm more familiar with the method of projection you describe, F dot normalised N.

The code is basically like this for each wheel.

side = car.xAxis;

sideForceProjection = dot(velocity, side)/dot(side, side);

velocity.x -= sideForceProjection*side.x;
velocity.y -= sideForceProjection*side.y;
velocity.z -= sideForceProjection*side.z;

This results in a drag racing car that can't steer left or right ;)

So now I'm going to find the side vector of the front wheels and apply that, and then work on making the friction perhaps a tad more natural feeling.

I'm imagining that when I have the front wheels working, the car is going to feel very on rails, a bit like Ridge Racer or Outrun when you're not drifting.

I think I'll make it marginally more complex. Possibly have a threshold for the amount of force acting on the side of the car, and if the force is low, apply ALL the friction as per above, and when the car is going faster, apply a smaller percentage of it, to give the handling a slightly softer feel.

[Edited by - rumblesushi on December 6, 2010 7:10:52 AM]
Quote:Original post by rumblesushi
Hey Emergent, oh I know what N is. What I mean is, how is the N after the projection part of the equation? Because the projection of the vector F onto the axis N, is simply the dot product divided by N squared right? With it producing a value between 0 and 1 if they are parallel along that axis.


What you're calling the "projection onto N" I would call the "component along N."

The component of F along N is a scalar.
The projection of F onto N is a vector.

Lemme break it down.

I wrote,


which can be written


since .

This may be more familiar to you, since is just n normalized. Yet more simply, letting u be ,

.

In this equation,

1.) is the component of f along u.
2.) is the projection of f onto u.
3.) is the projection of f onto u's orthogonal complement. I.e., it's the part of f that's orthogonal to u.
You're absolutely right, I was describing a scalar. Thanks for the explanation. Because I come from a design/photography background, rather than maths etc, I understand code much better than traditional maths syntax.
By the way thanks to both of you for the help, it's appreciated. Because I'm new to vehicle physics, I've been feeling a bit lost in regards to some of the aspects of handling/physics. Looking at it, it seems simple now.

I've implemented the same friction model on the front wheels now by copying the car's side vector and rotating it by the steering angle.

It works as expected, but not without some side effects. Basically, this large sideways friction force being exerted causes the constraints to go crazy at medium to high speeds. Also I'm not sure why at all, but it seems to have lessened the effect of gravity in some ways.

The front wheels specifically have a tendency to just rise up now, with the car ending up on it's rear, flipping around like a fish. Odd, I can't see where this force is coming from.

Apart from dramatically diluting this friction force at higher speeds, to allow some horizontal sliding, do you have any tips of how to build on this friction model a bit?

Emergent, you mentioned implementing a centripetal force right?

Cheers.
Quote:Original post by rumblesushi
causes the constraints to go crazy at medium to high speeds.

In what way?

Quote:Emergent, you mentioned implementing a centripetal force right?


I hadn't been thinking in the context of a multiple-wheels model. With multiple wheels, cetripital force should arise naturally as the sum of the constraint forces.

This topic is closed to new replies.

Advertisement