Networking - UDP

Hi Pandas!

I am using “Panda3D-1.0.5\samples\Feature-Tutorials–Collision-Detection”
to test our VR-Tracking equipment. My job is to replace the mouse-scanning (to rotate the mesh) with UDP-messages from another computer (server).
So, I get the UDP-datagrams and extract my necessary information (roll, pitch, yaw).

But: while running the Panda-program, there is a latency about 1-2 seconds, from sending UDP-datagrams (server) until the scene is updated with new angles for the mesh.

Problem: I got latency (1-2 seconds) from receiving UDP-datagrams in a Panda3D-World


from socket import *

# Set the socket parameters
host = "localhost"
port = 5000
buf = 1024
addr = (host,port)

# Create socket and bind to address
UDPSock = socket(AF_INET, SOCK_DGRAM)
UDPSock.bind(addr)

...

udpData, addr = UDPSock.recvfrom(buf)
self.maze.setR(float(getRoll(udpData)))
self.maze.setP(float(getPitch(udpData)))

This code works fine (without latency) in a non-Panda3D (pure python) environment.


I tried the ConnectionManager / RecentConnectionReader / NetDatagram API also, but without success (can’t get UDP-datagrams).


from pandac.ConnectionManager import *
from pandac.ConnectionReader import *
from pandac.NetDatagram import *

self.conMgr = ConnectionManager()
self.udpSock = self.conMgr.openUDPConnection(PORT)
self.udpSock.setReuseAddr(True)
self.udpReader = RecentConnectionReader(self.conMgr)

# get gata from server
myData = NetDatagram()
self.udpReader.getData(myData)

print myData.getMessage()
# nothing happens :(

Pls help, Sebastian.

I don’t know why the standard socket library would be introducing such an enormous latency in a Panda3D environment–that’s very strange. Maybe it has something to do with the graphics card interfering somehow. Have you tried it without rendering? (You could remove the ‘igLoop’ task by hand, just for the sake of testing; that’s the one that’s responsible for rendering.(

As to the Panda interfaces, you should set raw mode on your connection reader with:

self.udpReader = RecentConnectionReader(self.conMgr)
self.udpReader.setRawMode(1)

Since without raw mode, it will expect a two-byte Panda header on every packet. Also, you should check for a packet to have arrived with a call to dataAvailable() before you try to get the data, something like this:

if self.udpReader.dataAvailable():
    myData = NetDatagram()
    if self.udpReader.getData(myData):
        myData.dumpHex(ostream)

David

Removing the ‘igLoop’ brings the solution.
No more latency while receiving UDP datagrams in a Panda3D-World.
But also no rendering, needless to say. How to synchronise both?

Using the setRawMode(1) option had no affect. Think I got no connection
with the ConnectionManager API anyway.
Is there example-sourcecode around?
Google only brings the CVS implementation of Panda3D.

I don’t understand why rendering should affect the socket library. Maybe it’s all single-threaded, and the socket library is blocking, waiting for each frame to finish rendering? What sort of frame rate are you getting?

Another thing you need to do with the Panda library is add your connection object to the connection reader–otherwise it will never read anything:


self.udpReader.addConnection(self.udpSock)

There are some examples of using the Panda network library in direct/src/cluster. This is all TCP stuff, but the network library is designed to present almost the identical interface for UDP. There is also some actual UDP being used by the PStats server in pandatool/src/pstatclient, although that code is all C++ and might be hard to follow for a Python programmer.

David