Friction Problem

Started by
0 comments, last by Monder 18 years, 9 months ago
I've been trying to convert my game's physics system to be frame-independent, but ran into a problem with resistive forces (friction, drag, etc.). Acceleration due to resistive forces always ends up being several thousand times what it should be, overcoming both current velocity and acceleration (ex: if velocity = 10 and standard acceleration = 1, then acceleration due to friction might be in the vicinity of -7000). I've included a copy of my "vehicle" class (written in Java) below, simplified operate in only one dimension. I think I made some sort of mistake either in the way I calculate the vehicle's drag coefficient in the constructor, or the way I integrate resistive force in the "updatePhysics" method, but I'm having trouble working it out. I'd appreciate any suggestions anyone can offer.
 

class Vehicle 
{
	float  maxSpeed = 0;
	double engineAcceleration = 0;
	float  xDragCoefficient = 0;
	
	private float xPosition = 0;
	private float xSpeed = 0;
	private float xAcceleration = 0;
	private float xResistance = 0;
	
	public Vehicle(int newMaxSpeed, int newEngineAcceleration)
	{
		//This is the maximum speed this vehicle should attain under its own power (per millisecond)
		maxSpeed = new Double(newMaxSpeed*0.001).floatValue();
		
		//This is the acceleration caused by the force of the vehicle's engine (per millisecond)  
 		engineAcceleration = new Double(newEngineAcceleration*0.001).floatValue();

		//This represents the drag coefficient of the vehicle's "front" cross-section.
		//It should keep the vehicle's velocity (xSpeed) from exceeding maxSpeed under 
		//engine power alone.
		xDragCoefficient = new Double(2*engineAcceleration/(2*maxSpeed + engineAcceleration)).floatValue();
	}
	
	public void updateVehicle()
	{
		//The engine is accelerating the vehicle forward, possibly in addition to external forces
		xAcceleration += engineAcceleration;
		
		//The motion of the vehicle is resisted by its cross-sectional drag, possibly in addition to other resistive forces
		xResistance += xDragCoefficient;	
		
		updatePhysics();			
	}


	private void updatePhysics()
	{
		//Get the number of milliseconds that have passed since the last update cycle
		int time = Test.getElapsedTime();
		
		//Temporarily store the initial velocity
		float xSpeedInitial = xSpeed;
		
		//Integrate the acceleration due to standard forces (acceleration is constant over a single cycle)
		xSpeed += xAcceleration*time;

		//Determine the average velocity over this cycle in absence of resistive forces
		float averageXSpeed = (xSpeedInitial + xSpeed)/2;
		
		//Determine the average resistive acceleration over this cycle
		float resistanceXAcceleration = (-xResistance*(averageXSpeed)*time);
			
		//Integrate the acceleration due to resistive forces
		xSpeed += resistanceXAcceleration*time;
		
		//Update the possition by integrating the average speed, now that resistive forces are accounted for
		xPosition += ((xSpeedInitial + xSpeed)/2)*time;
		
		//Set Acceleration and Resistance to zero in preparation for the next cycle
		xAcceleration = 0;
		xResistance = 0;
	}
}



Advertisement
Why not do your updatePhysics function something like this?

private void updatePhysics(){	//Get the number of milliseconds that have passed since the last update cycle	int time = Test.getElapsedTime();			xAcceleration = engineAcceleration - (xDragCoefficient * xSpeed) / mass		xSpeed += xAcceleration*time;	xPosition += (xSpeed)*time;}


That's just using simple euler integration (this may not suffice, it depends upon what you're actually doing, if it's a simple physics simulation you may get away with it) and models the resistive force experienced by the car as F = kv where k is a constant (your xDragCoefficient) and v is the current speed).

You'll also need to calculate your drag coefficient differently and if I've got my maths right (it's been a while since I've done anything like that so I may have got it wrong) you can do it like this:

xDragCoefficient = new Double(mass * engineAcceleration / maxSpeed)


Oh and to convert your acceleration to milliseconds you need to multiply by 0.0012

Also why are xAcceleration and xResistance class variables? Why aren't they just local variables in updatePhysics?

This topic is closed to new replies.

Advertisement