PS2 Linux Programming
Network Car Control
Introduction
In this tutorial the application provided in the tutorial "Remote Camera Control Using UDP" is extended/modifies slightly to illustrate the control of a racing car over a network. There are two applications running, one on a Windows PC which controls the movement of one of the cars with the arrow keys. The other applications runs on the PS2 and controls the other car movement with the control pad. Berkeley Sockets are used on the PS2 and Windows Sockets are used on the Windows PC. The User Datagram Protocol (UDP) is used to perform the data transfer over the network.
The Example Code
The windows application simply obtains key presses from the keyboard, packages up any information to be sent, and sends it over the network to the IP address of the PS2 on the network (note that the IP address of the PS2 needs to be hard coded into the Windows application). The Windows program in short and simple and is repeated here for clarity. Note that the PS2 application does not actually do anything with the A,D,S,W keys, only the arrow keys are processed.
void main (void)
{
CUDPSocket UDPSocket;
char Buffer[PACKETSIZE], * pBuffer;
UDPSocket.Initialise();
UDPSocket.SetDestinationAddress("192.168.2.100", 1500);
while(1)
{
pBuffer = Buffer;
memset( Buffer, 0, PACKETSIZE );
if (GetAsyncKeyState(VK_ESCAPE)) return;
if (GetAsyncKeyState('A')) *pBuffer++ = 'A';
else if (GetAsyncKeyState('D')) *pBuffer++ = 'D';
if (GetAsyncKeyState('S')) *pBuffer++ = 'S';
else if (GetAsyncKeyState('W')) *pBuffer++ = 'W';
if (GetAsyncKeyState(VK_UP)) *pBuffer++ = 'F';
else if (GetAsyncKeyState(VK_DOWN)) *pBuffer++ = 'B';
if (GetAsyncKeyState(VK_LEFT)) *pBuffer++ = 'L';
else if (GetAsyncKeyState(VK_RIGHT))*pBuffer++ = 'R';
*pBuffer = 0;
if(*Buffer)
{
printf("%s\n", Buffer);
UDPSocket.Send(Buffer);
}
Sleep(50);
}
}
The pseudo code for the game loop of the PS2 application is as follows:
Get input from control pads;
Update camera;
Update Local car position;
Get input from the network;
Update network car position;
Render all objects;
The processing of the network messages is carried out using the following code:
// Get any car movements from the network
// Clear buffer
memset(NetMsg, 0x0, PACKETSIZE);
// reset the pointer
pNetMessage = NetMsg;
// receive message
int BytesReceived = UDPSocket.Receive(NetMsg);
// do net processing only if
there is a message
if(BytesReceived > 0)
{
//printf("Got Something -> %s\n", NetMsg);
do
{
if (*pNetMessage == 'F') Forward = 0.5f;
else if (*pNetMessage == 'B') Forward = -0.5f;
if (*pNetMessage == 'L') Rotate = 0.05f;e
lse if (*pNetMessage == 'R') Rotate = -0.05f;
pNetMessage++;
}while(*pNetMessage != 0);
}
Firstly the incoming receive buffer is cleared to 0 and a pointer to the buffer is initialised to the start of the buffer. A non-blocking call to receive from the socket in made. UDPSocket::Receive() returns the number of bytes received or -1 if there is no data to read. If there is incoming data, the message array is scanned for appropriate key press data and the required changes to the car position are made. No processing is undertaken if there is no incoming data, making this a fast and efficient method of dealing with the network connection.
Running The Applications
Compile and run the application on the PS2 and a scene is rendered on screen with two cars located on a basic terrain as can be seen in the accompanying screen shot. One car is controlled with the control pad, the other with the application running on the Windows PC. Both application are self contained and will run successfully without any requirement for the the other to be operational.
Running the Windows application provided the ability to remotely control the position of the car using the arrow keys. Execute the application and control the car position with the keys. It is possible to start and stop the windows application without any adverse affect on the PS2 application.
This tutorial illustrates a simple method of using the UDP protocol to control the movement of a car over a network. There are many ways in which the application can be enhanced and extended. It may be noticed that due to the slow update rate of the network data, and due to the possible congestion of the network being used, the motion of the car under remote control may be jerky and uneven. This is a situation where “dead-reckoning” can be employed to smooth out the camera movement and the reader is encouraged to investigate dead-reckoning algorithms and incorporate them into this application.
Dr Henry S Fortuna
University of Abertay Dundee