UDP Network control of BGE

Here is a simple sample *.blend file and a python script to drive the “player” from data received over the network using UDP. Its set up to use “localhost” so you can run Blender and the python script on the same computer for testing. It only really becomes useful with Blender on one machine and the controller on another like might exist in a virtual reality type setting.

I’m posting this because Googling didn’t find a straight answer about how to do such a thing. I did quickly find the BZoo project which is far more elaborate and uses TCP, and the OSC network sound loader (http://blenderartists.org/forum/archive/index.php/t-69804.html).

I put what I learned together from these and modified Social’s Beginning BGE Python sample *.blend (http://blendenzo.com/tutBeginningBGEPython.html) to show how a remote application can drive the player across a UDP network connection.

I’m new to Blender and Python so I make no claims as to it being the “best” way. In fact I’d love to have a better way or any improvements pointed out to me.

We envision a three computer setup. One running Blender to control the visual scene, one running a servo motion base, and the master reading sensors and running the contol algorithms to drive the visuals and motion base via network connections. We already have one such setup using Vizard for the visuals, I’m looking to avoid buying more $5000 Vizard software.

Tested/developed on Ubuntu 8.04 with Blender 2.45

–wally.

PS Can’t seem to upload the python script to drive the thing. Its short so I’ll paste it here: It just drives the player in a simple Lissajous curve.
-----------------------------------UDPdriverScript.py----------------------------------
import socket
import struct
import math
import sys, time

replace localhost with network name of game machine defined in game blend

HOST, PORT = “localhost”, 9999

SOCK_DGRAM is the socket type to use for UDP sockets

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

for i in range(0,4000):
phi = 3.141592653589 * 2 * i / 200
theta = math.sin(phi/3) / 300
y = math.cos(phi/11) / 20
data=struct.pack(’<ff’,theta,y)
sock.sendto(data, (HOST, PORT))
time.sleep(0.0333) # try for 30fps motion updates

data=struct.pack(’<ff’,0,0)
sock.sendto(data, (HOST, PORT))

sock.close()
-------------------------------------------end script--------------------------------------------

Attachments

NetValuesTest_py.blend (195 KB)

The cut and paste of the python test driver script seems to have lost the indent which is crucial for Python.

All the lines starting with “for i in range(0,4000)” thru “time.sleep(0.0333)” must be at the same level of indent for the loop to work correctly.

I’ll try again:
-----------------------------------UDPdriverScript.py----------------------------------


import socket
import struct
import math 
import sys, time


# replace localhost with network name of game machine defined in game blend
HOST, PORT = "localhost", 9999  

# SOCK_DGRAM is the socket type to use for UDP sockets
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  
for i in range(0,4000):
      phi = 3.141592653589 * 2 * i / 200
      theta = math.sin(phi/3) / 300
      y = math.cos(phi/11) / 20
      data=struct.pack('&lt;ff',theta,y)
      sock.sendto(data, (HOST, PORT))
      time.sleep(0.0333)              # try for 30fps motion updates

data=struct.pack('&lt;ff',0,0)
sock.sendto(data, (HOST, PORT))

sock.close()

-------------------------------------------end script--------------------------------------------

This script is just the simplest way I could think of to command the BGE “player” via UDP network packets.

–wally.

Edit: Attempt to fix using code tags.
Thanks, Moguri

Looks like the posting engine suppresses leading whitespace :frowning:

–wally.

That’s what code tags are is for.

Either use the # button to insert the tags, or enter them yourself.


Replace "{" and "}" with "[" and "]"
{code}
Your code
{/code}

Also, here’s a tutorial written by andrew-101 about networking with Blender:
http://tba-creations.leveluphost.com/index.php/Tutorials/creating-a-server-for-a-game.html

Also, here’s a tutorial written by andrew-101 about networking with Blender:
http://tba-creations.leveluphost.com…or-a-game.html

I’d found this one, but it is based on TCP not UDP, and doesn’t seem as complete as the BZoo project if you need this level of multi user complexity.

If you need logins and such UDP is not appropriate. If you need bidirectional connections not on your local subnet, UDP is usually not appropiate as you end up re-inventing TCP badly to account for error handling.

But where UDP wins is low latency one-way (master-slave) data flow where the appropiate error handling consits of “ignore it, catch up next frame”.

–wally.

Hmm, I think you should make something to choose IP to “connect to server” and then send data.

The BGE is the server, only the port really matters, as the IP address is what it is on whatever interface you choose to use (if there are more than one), but the clinet script needs to know both the port number and IP address of the listener. My sample blend & driver Python script is set up to use localhost so you can test in with a single computer. If you choose to use the scheme I’ve demo’d, you can modifiy it to meet your needs as you see fit. UDP is about a “free form” as it gets.

Actually UDP does not have connections, a UDP server is a bit of a misnomer. You can send data to any UDP port on a target machine and a packet will go out the wire, if nothing is listening on that port, nothing else happens, you get no error notification.

If you need error handling, you need to use TCP and accept its higher latencies, there is no free lunch. For my application minimal latency is crutial and any “errors” can be ignored and the scene “corrected” next frame when the next valid command packet comes in. On a local subnet the raw error rate is very low, on a network dedicated to only the communicating machines, its virtually error free if the hardware involved is not defective.

So in my “Virtual Reality” setup I have two listener machines (“servers” or slaves) and one talker (“client” or master) that sends command packets to the two slaves, communication is one directional, the listeners never need to talk back in my situation.

The Python socket docs show how to use sendto/recv pairs to “handshake” UDP communication, if you need more feedback than this, you should probably be using TCP instead of UDP.

HTH,
–wally.

what does ‘<ff’ means or does?

You oughtn’t be digging this up, but considering that someone may find this useful in the future;
He’s used struct;
< indicates little endian byte order
ff indicates packing two floats in succession.