Use of a More Recent Browser is Recommended
This site uses modern HTML5 features and may not render correctly on earlier browsers. If you use Internet Explorer, version 11 and later is recommended.
import socketimport timeimport threading#Edit the following 3 variables to match your configurationimage_directory="e:/romo-images" #directory to store imagesmy_ip=[192,168,123,2] #your IPromo_ip=[192,168,123,3] #IP of the romoromo_port=21133romo_ip_str=".".join(map(str,romo_ip))my_ip_str=".".join(map(str,my_ip))buf=""for oct in my_ip: buf+=chr(oct)for oct in romo_ip: buf+=chr(oct)for i in range(4): buf+=chr(0)#facessmile="È"love="É"excited="Ê"wink="Ë"random="Ì"frown="Í"angry="Î"confused="Ï"hush="Ð"crying="Ñ"#cameraflipcam="" #flips the camera from front to back or back to front#moves (for some reason the first move may need to be sent twice)s="p" #stopfl="i" #forward leftf="d" #forward straightfr="e" #forward rightrl="x" #rotate leftrr="h" #rotate rightbl="w" #back leftb="|" #back straightbr="{" #back right#control commandsinit=""startvideo=""shutdown=""abort=threading.Event()sock=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)#for type 3 face and move commandsdef send(cmd): tmp=""+cmd+buf sock.sendto(tmp,(romo_ip_str,romo_port))#for type 2 commands like init, startvideo, shutdowndef ctrl(cmd): if cmd==shutdown: abort.set() #let thread shut down time.sleep(1) elif cmd==startvideo: t=ThreadClass() t.start() tmp=""+cmd+buf sock.sendto(tmp,(romo_ip_str,romo_port))class ThreadClass(threading.Thread): def run(self): vsock=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) vsock.bind((my_ip_str,romo_port)) cnt=0 print("Image fetching thread started.") while not abort.isSet(): data,addr=vsock.recvfrom(15000) #Photos are less than 15K cnt+=1 scnt=str(cnt) for i in range(4-len(scnt)): scnt="0"+scnt if ord(data[0])==5 and ord(data[1])==0: #JPEG Image f=open(image_directory+"/image"+scnt+".jpg","w") f.write(data[14:]) f.close() vsock.close() print("Image fetching thread finished.")ctrl(init)#time.sleep(1)#ctrl(startvideo) #ctrl(shutdown) will shutdown the image capture thread, disconnect from the romo, and allow one to quit() the python interpreterA typical session that tells the Romo to smile, express love, move forward, and then stop might be:
python -i romo.py>>>send(smile)>>>send(love)>>>send(f)>>>send(s)>>>quit()A video capture session which starts video capture, moves forward, flips to the back camera, moves backward, and shuts down might be:
python -i romo.py>>>ctrl(startvideo)>>>send(f)>>>send(s)>>>send(flipcam)>>>send(b)>>>send(s)>>>ctrl(shutdown)>>>quit()Be careful in your use of video capture, the frames come rather quickly and are a little less than 15K each. When you turn on video capture in the script, it starts a background thread which captures them and writes them out to the specified directory as a sequence of JPEG files (I only pad for a 4 digit count). If you write a UI based on this, you'd normally just refresh the image every time a new one comes in. You could also do the same if you just want to add a command to copy out whatever the last received frame is (rather than keeping them all). Have fun!Update: I couldn't resist putting together a simple Python UI with a real-time video window and keyboard controls. You can download the full romo-ui.pyw program here. The UI requires a standard Python release which includes the Tkinter UI modules. It also requires the PIL library for the JPG image handling. The details about how to get these are in the comments to the program. If you've installed the Python environment with Tkinter, you can just launch the romo-ui.pyw program to start it -- make sure the phone on your Romo is already waiting for connections. You can exit the app either by typing "q" or deleting the window. Both should exit gracefully. The steering controls take advantage of the 9 key keypad (if you've got one). It should work in either numeric or non-numeric mode (see the code for the key mappings). Flipping the camera view is the "-" key and the faces are controlled by generally logical letter keys. It works great on my Romo (even with my hyper speed motor mod).Update2: I added automated discovery capability for Romos. You can download the full romo-ui2.pyw program here. You currently can't choose from multiple Romos (unless you hardcode the address) but it will auto-discover the first one it finds and connect to it. This involves both announcing that it's looking for Romos on the multicast channel as well as listening for responses (the default is only to look for about 5 seconds -- you can lengthen that time by setting it in the script). This was tested with the latest Romo iPhone app (v1.05).