Advertisement

Dead Reckoning Failure

Started by February 28, 2005 02:35 PM
1 comment, last by GodlyGamr 19 years, 11 months ago
I've been working on my dead reckoning algorithm for almost a week now.


Position DRCalc(Position lastPos, int direction, float lastUpdate, float timeSnapshot){

	Position drGuess;

	drGuess.x = (lastPos.x + (float((d3d.GetVelocity())) * float(cos(direction * (D3DX_PI/180))) * (float)(timeSnapshot - lastUpdate)));
	drGuess.z = (lastPos.z + (float((d3d.GetVelocity())) * float(sin(direction * (D3DX_PI/180))) * (float)(timeSnapshot - lastUpdate)));

	if (isMoving)
		return drGuess;
	else return myPos;

}

void DRCheck(float timeSnapshot){

	if ((fabs((myPos.x - DRCalc(lastPosition, DRdirection, lastUpdate, timeSnapshot).x)) > DRepsilon) || (fabs((myPos.z - DRCalc(lastPosition, DRdirection, lastUpdate, timeSnapshot).z)) > DRepsilon)){
		FillPacket(1, 0, lastPosition.x, lastPosition.z, myPos.direction, myPos.facing, 0.4);
		sendto(s, (char*)&outPacket, sizeof(outPacket), 0, (SOCKADDR*)&RecvAddr, sizeof(RecvAddr));
		lastUpdate = (float)timeGetTime();
		lastPosition.x = myPos.x;
		lastPosition.z = myPos.z;
		lastPosition.direction = myPos.direction;	
	}
}

...

					if (KeyDown(DIK_UP)){
						isMoving = true;
						myPos.x += (float(d3d.GetVelocity()) * float(cos(((-1 * d3d.GetFacing()) + 270) * (D3DX_PI/180))));
						myPos.z += (float(d3d.GetVelocity()) * float(sin(((-1 * d3d.GetFacing()) + 270) * (D3DX_PI/180))));
						myPos.direction = ((d3d.GetFacing() * -1) + 270);
					}
					if (KeyDown(DIK_DOWN)){
						isMoving = true;
						myPos.x -= (float(d3d.GetVelocity()) * float(cos(((-1 * d3d.GetFacing()) + 270) * (D3DX_PI/180))));
						myPos.z -= (float(d3d.GetVelocity()) * float(sin(((-1 * d3d.GetFacing()) + 270) * (D3DX_PI/180))));
						myPos.direction = ((d3d.GetFacing() * -1) + 450);
					}


The seemingly strange math when moving the model is due to the model facing 270 degrees when first loaded (for some reason, I haven't been able to get it to look right with any other numbers there). Right now, the client is calling DRcheck about 60 times per second (a lot, but didn't feel like setting a new timer). When the client sends a new update to the server, it takes the player's current x, z, direction, as well as a timestamp to use for the comparison. There has to be a problem with the calculation somewhere, but I can't figure out where. Thanks in advance, Jeff EDIT: can't figure out code tags... EDIT 2: fixed
You would probably get better replies if you actually described what the problem is.

- What behavior do you desire?
- What behavior are you observing?
- How is the code supposed to achieve the desired behavior?
enum Bool { True, False, FileNotFound };
Advertisement
Quote:
What behavior do you desire?


Hopefully, this code will eventually decrease the number of updates that need to be sent out by the client. Every so often, i check the player's position against a predicted position, and if the client is within an epsilon of the prediction, an update needn't be sent. Basically, in a fully working sample, as long as a client continued to move in one direction without turning, an update would not need to be sent.

By taking the position of the last sent update and adding to it the:

(velocity * direction * time)
x = cos(direction) z = sin(direction)

the client should be able to predict where a client should be.

Quote:
What behavior are you observing?


I set up a few different packet formats to be sent to the server (not so much different formats, but containing different data). The client's actual position is being calculated correctly, as both my clientside movement of the model and the correctness of the positions received by the server. However, when sending the absolute value of the

(client's actual position - client's predicted position)

the server outputs data showing that the predicted position could be as much as 20 or 30 units off. Since I'm only using a velocity of 0.5, such a variation doesn't seem practical.

When the player is facing 0 degrees, the z value of the DR check passes, which makes sense because the z position should not be changing. However, when the player is facing 90 degrees, the x value of the DR check varies and the z value stays constant at 0.5, strangely enough.

Upon closer inspection of the values of the predicted position, it appears that the z values are accurate, but the x values are strangely off. Even when facing 90 degrees when the x value should not change, the predicted values range from 4 to 18 and possibly higher (when standing at x = 0).

Quote:
How is the code supposed to achieve the desired behavior?


Think I may have accidentally answered this one in the first part.

Sorry for the vagueness of the OP.

Thanks again,
Jeff

This topic is closed to new replies.

Advertisement