Hi again
I figured out a strange “lag”-problem when I use sockets in a certain way:
In the beginning of my project, I used a very straight script for revieving data from a socket. It looks like this and is triggered by an always sensor:
import socket
import struct
import GameLogic as gl
import Mathutils as m
ip = "192.168.1.10"
port = 1511
multicastAdd = "239.255.42.99"
mreq = struct.pack('4sl', socket.inet_aton(multicastAdd), socket.INADDR_ANY)
sT = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sT.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sT.bind((ip,port))
sT.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
#sT.setblocking(0)
try:
# recieve data
data, addr = sT.recvfrom(10240)
ID, bytes, frame, markerSetCount, unknownMarker, rigidBodys = struct.unpack("<HHIIII",data[:20])
if markerSetCount == 0:
rbs = []
pos = []
quat = []
for n in xrange(rigidBodys):
rbs.append([])
pos.append([])
quat.append([])
rb, posX, posY, posZ, quatW, quatX, quatY, quatZ, mCount, errors = struct.unpack("<IfffffffIf",data[((n*40)+20):((n*40)+60)])
rbs[n].append(rb)
# putting data in rbs[]
pos[n] = m.Vector([rbs[n][1],rbs[n][2],rbs[n][3]])
quat[n] = m.Quaternion([-rbs[n][4],rbs[n][6],rbs[n][5],-rbs[n][7]])
scene = gl.getCurrentScene()
camera = scene.objects["OBview"]
camera.worldPosition = pos[1]
camera.worldOrientation = quat[1]
# doing more stuff with the data...
except socket.error:
pass
It worked fine, although I was wondering if it would be that good to establish the socket connection new in every frame!
So these days I tried around and tried the two following versions.
init() called once in the beginning, recv() with a pulsed always sensor again:
import socket
import struct
import GameLogic as gl
import Mathutils as m
def init():
ip = "192.168.1.10"
port = 1511
multicastAdd = "239.255.42.99"
mreq = struct.pack('4sl', socket.inet_aton(multicastAdd), socket.INADDR_ANY)
gl.sT = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
gl.sT.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
gl.sT.bind((ip,port))
gl.sT.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
#gl.sT.setblocking(0)
def recv():
try:
# recieve data
data, addr = gl.sT.recvfrom(10240)
ID, bytes, frame, markerSetCount, unknownMarker, rigidBodys = struct.unpack("<HHIIII",data[:20])
if markerSetCount == 0:
rbs = []
pos = []
quat = []
for n in xrange(rigidBodys):
rbs.append([])
pos.append([])
quat.append([])
rb, posX, posY, posZ, quatW, quatX, quatY, quatZ, mCount, errors = struct.unpack("<IfffffffIf",data[((n*40)+20):((n*40)+60)])
rbs[n].append(rb)
# putting data in rbs[]
pos[n] = m.Vector([rbs[n][1],rbs[n][2],rbs[n][3]])
quat[n] = m.Quaternion([-rbs[n][4],rbs[n][6],rbs[n][5],-rbs[n][7]])
scene = gl.getCurrentScene()
camera = scene.objects["OBview"]
camera.worldPosition = pos[1]
camera.worldOrientation = quat[1]
# doing more stuff with the data...
except socket.error:
pass
And finally I tried this one, where only recv() is called by an always sensor:
import socket
import struct
import GameLogic as gl
import Mathutils as m
ip = "192.168.1.10"
port = 1511
multicastAdd = "239.255.42.99"
mreq = struct.pack('4sl', socket.inet_aton(multicastAdd), socket.INADDR_ANY)
sT = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sT.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sT.bind((ip,port))
sT.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
#sT.setblocking(0)
def recv():
try:
# recieve data
data, addr = sT.recvfrom(10240)
ID, bytes, frame, markerSetCount, unknownMarker, rigidBodys = struct.unpack("<HHIIII",data[:20])
if markerSetCount == 0:
rbs = []
pos = []
quat = []
for n in xrange(rigidBodys):
rbs.append([])
pos.append([])
quat.append([])
rb, posX, posY, posZ, quatW, quatX, quatY, quatZ, mCount, errors = struct.unpack("<IfffffffIf",data[((n*40)+20):((n*40)+60)])
rbs[n].append(rb)
# putting data in rbs[]
pos[n] = m.Vector([rbs[n][1],rbs[n][2],rbs[n][3]])
quat[n] = m.Quaternion([-rbs[n][4],rbs[n][6],rbs[n][5],-rbs[n][7]])
scene = gl.getCurrentScene()
camera = scene.objects["OBview"]
camera.worldPosition = pos[1]
camera.worldOrientation = quat[1]
# doing more stuff with the data...
except socket.error:
pass
I was suprised how much performance I got by using the second or third version, compared to the first. Framerate went from ~45 to almost 80.
BUT: with script no. 2 and 3, I get a latency of around 1 second!
With the first script, the object (“camera” in this sample) reacts in realtime based on the streamed data.
The point is, that I cannot accept that second of latency in my project and that I really would need that preformance boost. So I try to find out, where that latency is comming from and how to remove it. Maybe someone could help me out with this?
I checked the blocking option of the socket, that does not make any difference.
Of course it’s hard to test if you don’t have a stream with data to try around, but maybe someone got a hint for me.
Greetings,
Quen