Sign in to follow this  

Simulate turning radius of a car

This topic is 1108 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi,

 

I am a total newbie in programming and try to code my very first game.

 

However I have problems with simulating the turning radius of a car, is there any solution to that?

 

In my game I am currently rotating my vehicle like shown below, but in real life a car should have always a steady turning radius, no matter of speed. Am I right? In the code below the car turns nearly on the spot when driving with 0.000000001 of speed...

how can I prevent that?

void loop() {
     if( currentSpeed != 0 ) {
          if( desiredRotation > 0 ) {
               rotation += rotationSpeed;
               desiredRoation -= rotationSpeed;
               dx = Math.sin( rotation );
               dy = Math.cos( rotation );
          } else if( desiredRotation < 0 ) {
               rotation -= rotationSpeed;
               desiredRoation += rotationSpeed;
               dx = Math.sin( rotation );
               dy = Math.cos( rotation );
          }

          x += dx * speed;
          y += dy * speed;
     }
}

There are a lot of games out there which make extensive use of cars, tanks and other vehicles - like Halo, Battlefield, GTA, etc.... . So there has to be some kind of common practice in simulating car behaviours!?

Any sources/articles to this topic are very welcome.

Also if you could make comments about my code would be great. I don't know if this is good code or if I can make this code any better, any comments and critics are welcome. I am teaching this stuff myself, so I do not have a chance to get my code reviewed otherwise.

Thank you very much
With Best Regards

Share this post


Link to post
Share on other sites

but in real life a car should have always a steady turning radius, no matter of speed. Am I right?

 

This is likely more than you really need, but...

 

Nope. Turning radius depends on speed, as well as steering wheel position (and other factors**.) As the speed increases, the front wheels may slip less, provide more lateral steering force*** at the front of the chassis, and the radius decreases. However, if you're not simulating tire friction forces, you can choose to ignore it, or decrease the radius by some function based on speed that gives you a behavior you like.

 

**It's a fairly complicated situation. Unless you want to include it in your simulation, the friction forces generated by the wheels are dependent on the normal force on the suspension and the velocity of the tire on the surface. That is, the more weight there is on the wheel, the more force it can generate. For instance, at a fixed speed, a car on a flat surface has a larger turning radius than a car going through a banked turn. The banked turn itself turns the car, of course, but because the car is "pushing" into the banked surface, the downward force on the wheels increases, which, in turn, increases the maximum lateral force that can be generated. So, the front wheel slip at speed depends on the normal force (the weight) on the wheel.

 

Another example: when the front wheels are turned (EDIT: when the wheels are moving "forward",) it causes the chassis weight to shift slightly forward and to the outside of the turn, increases the normal force on the front wheels, increasing friction factors - such as lateral steering force.

 

As another example, when the driver pushes down on the accelerator, chassis weight shifts more to the back wheels, away from the front wheels, and the front wheels provide less lateral steering force. That's one reason dragsters compete on a straight track - it's difficult to steer when the front end lifts and the front wheels barely touch the ground - the lateral steering forces are greatly reduced because there's not much weight on the front wheels.

 

*** A demonstration of the importance of friction forces on turning radius - a car on ice has a much larger turning radius than on dry pavement, for the same steering angle and speed.

 

This link provides a diagram of the situation with regard to steering angle versus turn radius from which you can derive the turn radius.

 

With regard to your implementation, I would suggest you use a vector for the chassis direction, rotate that vector by a small angle per delta-time, based on the steering angle and speed. I.e., you don't want the chassis to change direction when the vehicle is stationary. It must be moving for the direction to change.

Edited by Buckeye

Share this post


Link to post
Share on other sites

Thanks for your answer.

Well yes this is a little bit too much right now, especially because I am still stuck on the rotation of the car itself biggrin.png

 

Your link gives me a very good idea about applying a proper rotation... I didn't knew this. So when rotating I have to rotate about a rotating point left or right to the back of the car. Makes sense!

Well now it goes to plain math and sin and cos (I hate these so much) >.<
 

Working now since a few hours on the solution but I am really stuck on the math itself, it would be so great if I hadn't to differ between turning and not turning and I guess there is a proper solution for that but right now I just hate sin and cos...

 

 

*Edit I found this useful article (subtopic "curves") which is similar to your link. However it sadly doesn't provide any useful math -.-

http://www.asawicki.info/Mirror/Car%20Physics%20for%20Games/Car%20Physics%20for%20Games.html

Edited by GameDev.net

Share this post


Link to post
Share on other sites

1) Dont use trigonometry, use (2D) martices and vectors (the matrix would have some kind of .fromAngle(anglehere) method that wraps up the trig)

2) Basically divide the change in angle by the speed of the vehicle, that was the idea (or in some other way make low speed = low turn rate)

Share this post


Link to post
Share on other sites

1) Dont use trigonometry, use (2D) martices and vectors (the matrix would have some kind of .fromAngle(anglehere) method that wraps up the trig)

2) Basically divide the change in angle by the speed of the vehicle, that was the idea (or in some other way make low speed = low turn rate)

 

2) Yeah I got that now, too I guess. (angularSpeed = currentSpeed / turningRadius)

I guess this is what you meant?

 

1) I don't really know what you mean by using matrices. I know how matrices work and how to calculate with them and I am also using them (using the given Matrix library) in my game to store everything on the GPU to calculate there further.
However I do not get what you mean by using matrices and vectors... how should I use them exactly? How can a matrice and a vector help me describing the turning of a car?

When I got it right, the only purpose of matrices is this:

draw( Shader shader ) {
     Matrix m = new Matrix();
     m.scale( scale );
     m.rotateZ( rotationZ );
     m.transform( x, y, 0 );
     shader.sendMatrix(  m );
}

This is the only way I have found out to use matrices actually. Every (game) programming tutorial I have found and read so far is only covering exactly this and nothing more. So I am stuck what you mean by "use matrices and vectors"!?

Share this post


Link to post
Share on other sites


So I am stuck what you mean by "use matrices and vectors"!?

 

You mentioned trigonometric functions so I immediately reacted by telling you to use vectors and matrices, because usually theyre enough.

 

I believe you would somehow multiply the car matrix with another matrix that has been offset and then rotated... I usually think about matrices in terms of working in the 'object space' of an entity and then moving the matrices from object to world space and the other way. So first youd calculate the object space rotation matrix for turning the car about a point (left/right of rear axel), then do something like carMatrix.toWorldSpace(localMatrix) to find the new matrix for the car.

 

I tend to use quite a lot of trial and error because im not that familiar working with matrices and get the order wrong...

Share this post


Link to post
Share on other sites

 


So I am stuck what you mean by "use matrices and vectors"!?

 

You mentioned trigonometric functions so I immediately reacted by telling you to use vectors and matrices, because usually theyre enough.

 

I believe you would somehow multiply the car matrix with another matrix that has been offset and then rotated... I usually think about matrices in terms of working in the 'object space' of an entity and then moving the matrices from object to world space and the other way. So first youd calculate the object space rotation matrix for turning the car about a point (left/right of rear axel), then do something like carMatrix.toWorldSpace(localMatrix) to find the new matrix for the car.

 

I tend to use quite a lot of trial and error because im not that familiar working with matrices and get the order wrong...

 

 Okay thanks.

Yeah Matrices are a whole math topic when studying specific math related subjects and can be used in many different ways and with many different "rules" including but not limited to describing points in space.
I had matrix calculations in university but none of them covered this topic.

I guess you are right. I could use an additional matrix but I tend not to do so as the matrix class shows up in the profiler very often, it is really expensive to calculate (with) them, so I rather write the whole calculation down and then try to reduce the calculation to gain speed. Trigonometry is just so expensive even for CPUs.

So the whole calculation overwhelmed me so I quit calculating the (nearly) exact solution and rather use a finite element method like so:

private final float minTurningRadius = 100;
private float speed, rotSpeed;

public void setSpeed( float speed, int turn ) {
	// turn is either >(+1) [turn left] or 0 or <(-1) [turn right]
	this.speed = speed;

	float turningRadius = this.maxTurningRadius * turn;

	if( turningRadius != 0 )
		rotSpeed = speed / turningRadius;
	else
		rotSpeed = 0;
}

public void loop() {
	if( speed != 0 ) {
		// finite element method
		if( rotSpeed != 0 ) {
			rot += rotSpeed;
			dx = (float) Math.cos( rot );
			dy = (float) Math.sin( rot );
		}
		x += dx * speed;
		y += dy * speed;
	}
}

Share this post


Link to post
Share on other sites

This topic is 1108 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this