mirror of
https://github.com/jjrobots/B-ROBOT_EVO2.git
synced 2026-02-20 11:21:23 +01:00
New version of BROBOT EVO2
This is the first oficial version of BROBOT EVO2. Enjoy!
This commit is contained in:
54
Blockly/python/BROBOT_Class.py
Normal file
54
Blockly/python/BROBOT_Class.py
Normal file
@@ -0,0 +1,54 @@
|
||||
# BROBOT PYTHON CLASS
|
||||
# Exampe 1: Simple commands
|
||||
# Before running the script you need to connect the PC to the BROBOT wifi
|
||||
# Remember, default password for Wifi network JJROBOTS_XX is 87654321
|
||||
|
||||
# author: JJROBOTS 2016
|
||||
# version: 1.01 (27/10/2016)
|
||||
# Licence: Open Source (GNU LGPLv3)
|
||||
|
||||
import socket
|
||||
import time
|
||||
import struct
|
||||
|
||||
# CLASS to control BROBOT
|
||||
class BROBOT(object):
|
||||
UDP_IP = "192.168.4.1" # Default BROBOT IP (with BROBOT JJROBOTS_XX wifi)
|
||||
UDP_PORT = 2222 # Default BROBOT port
|
||||
sock = 0
|
||||
def __init__(self):
|
||||
# Create default socket with UDP protocol
|
||||
self.sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
|
||||
|
||||
def sendCommand(self,OSCmessage,param):
|
||||
base = bytearray(OSCmessage) # OSC message
|
||||
param = bytearray(struct.pack(">f",param))
|
||||
message = base+param
|
||||
self.sock.sendto(message,(self.UDP_IP,self.UDP_PORT))
|
||||
time.sleep(0.05)
|
||||
|
||||
# Mode: 0 NORMAL MODE, 1 PRO MODE
|
||||
def mode(self,value=0.0):
|
||||
print "BROBOT Mode:",value
|
||||
if (value!=1): value = 0.0
|
||||
# Encapsulate the commands on OSC protocol UDP message and send...
|
||||
self.sendCommand(b'/1/toggle1/\x00\x00,f\x00\x00',value)
|
||||
|
||||
# Throttle command. Values from [-1.0 to 1.0] positive: forward
|
||||
def throttle(self,value=0.0):
|
||||
print "BROBOT Throttle:",value
|
||||
value = (value+1.0)/2.0 # Adapt values to 0.0-1.0 range
|
||||
self.sendCommand(b'/1/fader1\x00\x00\x00,f\x00\x00',value) #send OSC message
|
||||
|
||||
# Steering command. Values from [-1.0 to 1.0] positive: turn right
|
||||
def steering(self,value=0.0):
|
||||
print "BROBOT Steering:",value
|
||||
value = (value+1.0)/2.0 # Adapt values to 0.0-1.0 range
|
||||
self.sendCommand(b'/1/fader2\x00\x00\x00,f\x00\x00',value) #send OSC message
|
||||
|
||||
# Servo command. Values 0 or 1 (activated)
|
||||
def servo(self,value=0.0):
|
||||
print "BROBOT Servo:",value
|
||||
if (value!=1):value=0.0
|
||||
self.sendCommand(b'/1/push1\x00\x00,f\x00\x00',value) #send OSC message
|
||||
|
||||
BIN
Blockly/python/BROBOT_Class.pyc
Normal file
BIN
Blockly/python/BROBOT_Class.pyc
Normal file
Binary file not shown.
39
Blockly/python/Example1.py
Normal file
39
Blockly/python/Example1.py
Normal file
@@ -0,0 +1,39 @@
|
||||
# BROBOT PC CONTROL python script
|
||||
# Exampe 1: Simple commands
|
||||
# Before running the script you need to connect the PC to the BROBOT wifi
|
||||
# Remember, default password for Wifi network JJROBOTS_XX is 87654321
|
||||
|
||||
# author: JJROBOTS 2016
|
||||
# version: 1.01 (28/10/2016)
|
||||
# Licence: Open Source (GNU LGPLv3)
|
||||
|
||||
import time
|
||||
from BROBOT_Class import BROBOT # Import CLASS to control BROBOT
|
||||
|
||||
# BROBOT initialization
|
||||
myRobot = BROBOT()
|
||||
myRobot.mode(0) # Normal mode. optional: PRO MODE=1
|
||||
|
||||
# Example of sequence of commands to BROBOT:
|
||||
myRobot.servo(1) #Move servo
|
||||
time.sleep(0.25)
|
||||
myRobot.servo(0)
|
||||
time.sleep(0.25)
|
||||
myRobot.servo(1) #Move servo
|
||||
time.sleep(0.25)
|
||||
myRobot.servo(0)
|
||||
|
||||
myRobot.throttle(0.6) #Move forward
|
||||
time.sleep(1.2)
|
||||
myRobot.throttle(0) #Stop
|
||||
time.sleep(2)
|
||||
myRobot.steering(0.8) #Turn right
|
||||
time.sleep(2)
|
||||
myRobot.steering(0)
|
||||
time.sleep(0.25)
|
||||
myRobot.steering(-0.8) #Turn left
|
||||
time.sleep(2)
|
||||
myRobot.steering(0) #Stop
|
||||
myRobot.throttle(0)
|
||||
|
||||
|
||||
66
Blockly/python/Example2.py
Normal file
66
Blockly/python/Example2.py
Normal file
@@ -0,0 +1,66 @@
|
||||
# BROBOT PC CONTROL python script
|
||||
# Exampe 2: Brobot Dance
|
||||
# Before running the script you need to connect the PC to the BROBOT wifi
|
||||
# Remember, default password for Wifi network JJROBOTS_XX is 87654321
|
||||
|
||||
# author: JJROBOTS 2016
|
||||
# version: 1.01 (28/10/2016)
|
||||
# Licence: Open Source (GNU LGPLv3)
|
||||
|
||||
import time
|
||||
from BROBOT_Class import BROBOT # Import CLASS to control BROBOT
|
||||
|
||||
# BROBOT initialization
|
||||
myRobot = BROBOT()
|
||||
myRobot.mode(1) # PRO MODE
|
||||
|
||||
for i in range(0,2):
|
||||
myRobot.servo(1)
|
||||
time.sleep(0.15)
|
||||
myRobot.servo(0)
|
||||
time.sleep(0.15)
|
||||
|
||||
for i in range(0,3):
|
||||
myRobot.steering(0.5+i*0.1)
|
||||
time.sleep(0.25)
|
||||
myRobot.steering(0)
|
||||
myRobot.steering(-0.5-i*0.1)
|
||||
time.sleep(0.25)
|
||||
myRobot.steering(0)
|
||||
myRobot.steering(-0.5-i*0.1)
|
||||
time.sleep(0.25)
|
||||
myRobot.steering(0)
|
||||
myRobot.steering(0.5+i*0.1)
|
||||
time.sleep(0.25)
|
||||
myRobot.steering(0)
|
||||
myRobot.servo(1)
|
||||
myRobot.servo(0)
|
||||
|
||||
|
||||
for i in range(0,5):
|
||||
myRobot.throttle(0.3)
|
||||
time.sleep(0.08)
|
||||
myRobot.throttle(0)
|
||||
time.sleep(0.08)
|
||||
myRobot.throttle(-0.3)
|
||||
time.sleep(0.08)
|
||||
myRobot.throttle(0)
|
||||
myRobot.servo(1)
|
||||
myRobot.servo(0)
|
||||
|
||||
myRobot.steering(1)
|
||||
time.sleep(1)
|
||||
myRobot.steering(0)
|
||||
time.sleep(0.1)
|
||||
myRobot.steering(-1)
|
||||
time.sleep(1)
|
||||
myRobot.steering(0)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
67
Blockly/python/Example3.py
Normal file
67
Blockly/python/Example3.py
Normal file
@@ -0,0 +1,67 @@
|
||||
# BROBOT PC CONTROL python script
|
||||
# Exampe 3: Graphic User Interface to control BROBOT (using Tkinter python UI)
|
||||
# Before running the script you need to connect the PC to the BROBOT wifi
|
||||
# Remember, default password for Wifi network JJROBOTS_XX is 87654321
|
||||
|
||||
# author: JJROBOTS 2016
|
||||
# version: 1.01 (28/10/2016)
|
||||
# Licence: Open Source (GNU LGPLv3)
|
||||
|
||||
import socket
|
||||
import time
|
||||
import struct
|
||||
import Tkinter as tk
|
||||
from Tkinter import IntVar
|
||||
from BROBOT_Class import BROBOT # Import CLASS to control BROBOT
|
||||
|
||||
|
||||
# GRAPHIC USER INTERFACE
|
||||
class MainApplication(tk.Frame):
|
||||
throttle = 0
|
||||
steering = 0
|
||||
mode = 0
|
||||
myRobot = BROBOT()
|
||||
def draw(self):
|
||||
print "DRAW"
|
||||
def __init__(self,parent,*args,**kwargs):
|
||||
tk.Frame.__init__(self,parent,*args,**kwargs)
|
||||
self.parent = parent
|
||||
# GUI INIT: 2 sliders and 1 button
|
||||
self.t = tk.Scale(troughcolor="light yellow",from_=100,to=-100,width=40,length=200)
|
||||
self.t.pack(side=tk.LEFT,fill=tk.BOTH,expand=1)
|
||||
self.s = tk.Scale(troughcolor="light cyan",from_=-100,to=100,width=40,length=250,orient=tk.HORIZONTAL)
|
||||
self.s.pack(side=tk.LEFT,fill=tk.X)
|
||||
self.after(50,self.timer)
|
||||
self.b = tk.Button(bg="light green",repeatdelay=1,repeatinterval=50,width=10,height=2,text="SERVO",command=self.buttonCallback)
|
||||
self.b.pack(side=tk.LEFT)
|
||||
self.mode_control = IntVar()
|
||||
self.m = tk.Checkbutton(text="PRO MODE",variable=self.mode_control)
|
||||
self.m.pack()
|
||||
def buttonCallback(self):
|
||||
self.myRobot.servo(1)
|
||||
time.sleep(0.2)
|
||||
self.myRobot.servo(0)
|
||||
def timer(self): # Timer at 50ms interval to read slider values
|
||||
if (self.t.get()!=self.throttle):
|
||||
self.throttle = self.t.get()
|
||||
self.myRobot.throttle(self.throttle/100.0)
|
||||
#print "THROTTLE:",self.throttle
|
||||
if (self.s.get()!=self.steering):
|
||||
self.steering = self.s.get()
|
||||
self.myRobot.steering(self.steering/100.0)
|
||||
#print "STEERING:",self.steering
|
||||
if (self.mode_control.get()!=self.mode):
|
||||
self.mode = self.mode_control.get()
|
||||
self.myRobot.mode(self.mode)
|
||||
#print "MODE:",self.mode
|
||||
self.after(50,self.timer)
|
||||
|
||||
|
||||
# START APPLICATION
|
||||
if __name__=="__main__":
|
||||
root = tk.Tk()
|
||||
root.wm_title("BROBOT CONTROL")
|
||||
MainApplication(root).pack(side="top",fill="both",expand=True)
|
||||
root.mainloop()
|
||||
|
||||
|
||||
58
Blockly/python/Example4.py
Normal file
58
Blockly/python/Example4.py
Normal file
@@ -0,0 +1,58 @@
|
||||
# BROBOT PC CONTROL python script
|
||||
# Exampe 4: Controlling 2 BROBOTS in a coreography...
|
||||
# You should modify your BROBOT arduino code to connecto to your wifi network
|
||||
# BROBOT1 is on IP 192.168.1.101 and BROBOT 2 IP is 192.168.1.102
|
||||
|
||||
# author: JJROBOTS 2016
|
||||
# version: 1.01 (28/10/2016)
|
||||
# Licence: Open Source (GNU LGPLv3)
|
||||
|
||||
import time
|
||||
from BROBOT_Class import BROBOT # Import CLASS to control BROBOT
|
||||
|
||||
# BROBOT1 initialization
|
||||
myRobot1 = BROBOT()
|
||||
myRobot1.UDP_IP = "192.168.1.101"
|
||||
myRobot1.mode(0) # Normal mode. optional: PRO MODE=1
|
||||
|
||||
# BROBOT1 initialization
|
||||
myRobot2 = BROBOT()
|
||||
myRobot2.UDP_IP = "192.168.1.102"
|
||||
myRobot2.mode(0) # Normal mode. optional: PRO MODE=1
|
||||
|
||||
|
||||
# Example of sequence of commands to BROBOT:
|
||||
myRobot1.servo(1) #Move servo
|
||||
myRobot2.servo(1)
|
||||
time.sleep(0.25)
|
||||
myRobot1.servo(0)
|
||||
myRobot2.servo(0)
|
||||
time.sleep(0.25)
|
||||
myRobot1.servo(1) #Move servo
|
||||
myRobot2.servo(1)
|
||||
time.sleep(0.25)
|
||||
myRobot1.servo(0)
|
||||
myRobot2.servo(0)
|
||||
|
||||
myRobot1.throttle(0.4)
|
||||
myRobot2.throttle(0.4)
|
||||
time.sleep(0.75)
|
||||
myRobot1.throttle(0)
|
||||
myRobot2.throttle(0)
|
||||
time.sleep(1)
|
||||
myRobot1.steering(0.8) # Robot1 Turn right
|
||||
myRobot2.steering(-0.8) # Robot2 Turn left
|
||||
time.sleep(2)
|
||||
myRobot1.steering(0)
|
||||
myRobot2.steering(0)
|
||||
time.sleep(0.25)
|
||||
myRobot1.steering(-0.8) # Robot1 Turn left
|
||||
myRobot2.steering(0.8) # Robot2 Turn right
|
||||
time.sleep(2)
|
||||
myRobot1.steering(0) #Stop
|
||||
myRobot2.steering(0)
|
||||
myRobot1.throttle(0)
|
||||
myRobot2.throttle(0)
|
||||
|
||||
|
||||
|
||||
66
Blockly/python/server/BROBOT_Class.py
Normal file
66
Blockly/python/server/BROBOT_Class.py
Normal file
@@ -0,0 +1,66 @@
|
||||
# BROBOT PYTHON CLASS
|
||||
# Exampe 1: Simple commands
|
||||
# Before running the script you need to connect the PC to the BROBOT wifi
|
||||
# Remember, default password for Wifi network JJROBOTS_XX is 87654321
|
||||
|
||||
# author: JJROBOTS 2016
|
||||
# version: 1.01 (27/10/2016)
|
||||
# Licence: Open Source (GNU LGPLv3)
|
||||
|
||||
import socket
|
||||
import time
|
||||
import struct
|
||||
|
||||
# CLASS to control BROBOT
|
||||
class BROBOT(object):
|
||||
UDP_IP = "192.168.4.1" # Default BROBOT IP (with BROBOT JJROBOTS_XX wifi)
|
||||
UDP_PORT = 2222 # Default BROBOT port
|
||||
sock = 0
|
||||
def __init__(self):
|
||||
# Create default socket with UDP protocol
|
||||
self.sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
|
||||
|
||||
def sendCommand(self,OSCmessage,param):
|
||||
base = bytearray(OSCmessage) # OSC message
|
||||
param = bytearray(struct.pack(">f",param))
|
||||
message = base+param
|
||||
self.sock.sendto(message,(self.UDP_IP,self.UDP_PORT))
|
||||
time.sleep(0.05)
|
||||
|
||||
# Mode: 0 NORMAL MODE, 1 PRO MODE
|
||||
def mode(self,value=0.0):
|
||||
print "BROBOT Mode:",value
|
||||
if (value!=1): value = 0.0
|
||||
# Encapsulate the commands on OSC protocol UDP message and send...
|
||||
self.sendCommand(b'/1/toggle1/\x00\x00,f\x00\x00',value)
|
||||
|
||||
# Throttle command. Values from [-1.0 to 1.0] positive: forward
|
||||
def throttle(self,value=0.0):
|
||||
print "BROBOT Throttle:",value
|
||||
value = (value+1.0)/2.0 # Adapt values to 0.0-1.0 range
|
||||
self.sendCommand(b'/1/fader1\x00\x00\x00,f\x00\x00',value) #send OSC message
|
||||
|
||||
# Steering command. Values from [-1.0 to 1.0] positive: turn right
|
||||
def steering(self,value=0.0):
|
||||
print "BROBOT Steering:",value
|
||||
value = (value+1.0)/2.0 # Adapt values to 0.0-1.0 range
|
||||
self.sendCommand(b'/1/fader2\x00\x00\x00,f\x00\x00',value) #send OSC message
|
||||
|
||||
# Move speed, steps1, steps2
|
||||
def move(self,speed,steps1,steps2):
|
||||
print "BROBOT MOVE",speed,steps1,steps2
|
||||
base = bytearray(b'/1/move\x00\x00\x00')
|
||||
param1 = bytearray(struct.pack("h",speed))
|
||||
param2 = bytearray(struct.pack("h",steps1))
|
||||
param3 = bytearray(struct.pack("h",steps2))
|
||||
message = base+param1+param2+param3
|
||||
self.sock.sendto(message,(self.UDP_IP,self.UDP_PORT))
|
||||
#print len(message)
|
||||
#self.sendCommand(b'/1/move\x00\x00\x00\x00\x00\x00
|
||||
|
||||
# Servo command. Values 0 or 1 (activated)
|
||||
def servo(self,value=0.0):
|
||||
print "BROBOT Servo:",value
|
||||
if (value!=1):value=0.0
|
||||
self.sendCommand(b'/1/push1\x00\x00,f\x00\x00',value) #send OSC message
|
||||
|
||||
BIN
Blockly/python/server/BROBOT_Class.pyc
Normal file
BIN
Blockly/python/server/BROBOT_Class.pyc
Normal file
Binary file not shown.
183
Blockly/python/server/webserver.py
Normal file
183
Blockly/python/server/webserver.py
Normal file
@@ -0,0 +1,183 @@
|
||||
#!/usr/bin/python
|
||||
# Blockly interface for BROBOT block programming
|
||||
|
||||
# Remember to connect your wifi to your robot network JJROBOTS_XX password:8764321
|
||||
|
||||
# author: JJROBOTS 2017
|
||||
# version: 1.01 (10/03/2017)
|
||||
# Licence: Open Source (GNU LGPLv3)
|
||||
|
||||
from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer
|
||||
from os import curdir, sep
|
||||
import urlparse
|
||||
from BROBOT_Class import BROBOT
|
||||
import time
|
||||
import webbrowser
|
||||
import threading
|
||||
import socket
|
||||
|
||||
# BROBOT initialization
|
||||
myRobot = BROBOT()
|
||||
IP = myRobot.UDP_IP
|
||||
PORT = myRobot.UDP_PORT
|
||||
|
||||
HTTP2UDP_PORT = 8008
|
||||
PORT_NUMBER = 8080
|
||||
|
||||
# Telemetry port
|
||||
UDP_PORT = 2223
|
||||
|
||||
# Global variables
|
||||
global status
|
||||
global angle
|
||||
status = 0
|
||||
angle = 0.0
|
||||
|
||||
# Class to launch servers on different threads
|
||||
class ServerThread(threading.Thread):
|
||||
def __init__(self,port,handler):
|
||||
threading.Thread.__init__(self)
|
||||
self.port=port
|
||||
self.handler = handler
|
||||
|
||||
def run(self):
|
||||
server = HTTPServer(('localhost', self.port), self.handler)
|
||||
server.serve_forever()
|
||||
|
||||
|
||||
#Browser to handle HTTP to UDP conversion
|
||||
class HTTP2UDP(BaseHTTPRequestHandler):
|
||||
# Override address_string to avoid using name lookup
|
||||
def address_string(self):
|
||||
host, port = self.client_address[:2]
|
||||
#return socket.getfqdn(host)
|
||||
return host
|
||||
def do_GET(self):
|
||||
#print("GET request")
|
||||
self.send_response(200)
|
||||
self.send_header("Access-Control-Allow-Origin","*")
|
||||
self.send_header("Content-type", "text/html")
|
||||
self.end_headers()
|
||||
params = self.path
|
||||
params = params.split('?')
|
||||
if (len(params)>1):
|
||||
params = urlparse.parse_qs(params[1])
|
||||
if 'IP' in params.keys():
|
||||
print "IP: "+params['IP'][0]
|
||||
myRobot.UDP_IP = params['IP'][0]
|
||||
if 'PORT' in params.keys():
|
||||
print "PORT: "+params['PORT'][0]
|
||||
myRobot.UDP_PORT = int(params['PORT'][0])
|
||||
if 'ST' in params.keys():
|
||||
#print params['ST'][0]
|
||||
myRobot.steering(int(params['ST'][0])/100.0)
|
||||
if 'TH' in params.keys():
|
||||
#print params['TH'][0]
|
||||
myRobot.throttle(int(params['TH'][0])/100.0)
|
||||
if 'MV' in params.keys():
|
||||
mvparams = params['MV'][0].split(",")
|
||||
#print mvparams[0]+" "+mvparams[1]+" "+mvparams[2]
|
||||
myRobot.move(int(mvparams[0]),int(mvparams[1]),int(mvparams[2]))
|
||||
if 'MO' in params.keys():
|
||||
#print params['MO'][0]
|
||||
myRobot.mode(int(params['MO'][0]))
|
||||
if 'SE' in params.keys():
|
||||
#print params['SE'][0]
|
||||
myRobot.servo(int(params['SE'][0]))
|
||||
if 'RS' in params.keys():
|
||||
self.wfile.write(status)
|
||||
return
|
||||
if 'RA' in params.keys():
|
||||
self.wfile.write(angle)
|
||||
return
|
||||
self.wfile.write('OK')
|
||||
return
|
||||
|
||||
def log_request(self, code=None, size=None):
|
||||
pass # Do nothing...
|
||||
#print('Request')
|
||||
|
||||
|
||||
|
||||
#This class will handles any incoming request from
|
||||
#the browser
|
||||
class myHandler(BaseHTTPRequestHandler):
|
||||
|
||||
#Handler for the GET requests
|
||||
def do_GET(self):
|
||||
if self.path=="/":
|
||||
self.path="brobot/index.html"
|
||||
|
||||
try:
|
||||
#Check the file extension required and
|
||||
#set the right mime type
|
||||
|
||||
sendReply = False
|
||||
binary = False
|
||||
if self.path.endswith(".html"):
|
||||
mimetype='text/html'
|
||||
sendReply = True
|
||||
if self.path.endswith(".jpg"):
|
||||
binary = True
|
||||
mimetype='image/jpg'
|
||||
sendReply = True
|
||||
if self.path.endswith(".png"):
|
||||
binary = True
|
||||
mimetype='image/png'
|
||||
sendReply = True
|
||||
if self.path.endswith(".cur"):
|
||||
binary = True
|
||||
mimetype='image/x-win-bitmap'
|
||||
sendReply = True
|
||||
if self.path.endswith(".wav"):
|
||||
binary = True
|
||||
mimetype='audio/wav'
|
||||
sendReply = True
|
||||
if self.path.endswith(".mp3"):
|
||||
binary = True
|
||||
mimetype='audio/mpeg'
|
||||
sendReply = True
|
||||
if self.path.endswith(".gif"):
|
||||
binary = True
|
||||
mimetype='image/gif'
|
||||
sendReply = True
|
||||
if self.path.endswith(".js"):
|
||||
mimetype='application/javascript'
|
||||
sendReply = True
|
||||
if self.path.endswith(".css"):
|
||||
mimetype='text/css'
|
||||
sendReply = True
|
||||
|
||||
if sendReply == True:
|
||||
#Open the static file requested and send it
|
||||
if binary:
|
||||
f = open(curdir + sep + self.path,'rb')
|
||||
else:
|
||||
f = open(curdir + sep + self.path)
|
||||
self.send_response(200)
|
||||
self.send_header('Content-type',mimetype)
|
||||
self.end_headers()
|
||||
self.wfile.write(f.read())
|
||||
f.close()
|
||||
return
|
||||
|
||||
except IOError:
|
||||
self.send_error(404,'File Not Found: %s' % self.path)
|
||||
|
||||
try:
|
||||
#Create the HTTP to UDP server to send messages to robot
|
||||
ServerThread(HTTP2UDP_PORT,HTTP2UDP).start()
|
||||
#Create a web server and define the handler to manage the incoming requests
|
||||
ServerThread(PORT_NUMBER,myHandler).start()
|
||||
print "Started HTTP2UDP server on port ", HTTP2UDP_PORT
|
||||
print "Started httpserver on port " , PORT_NUMBER
|
||||
print "Opening browser... wait a moment..."
|
||||
time.sleep(2)
|
||||
url = "http://localhost:8080/brobot/index.html"
|
||||
webbrowser.open(url,new=2)
|
||||
while 1:
|
||||
pass
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print '^C received, shutting down the web server'
|
||||
exit()
|
||||
Reference in New Issue
Block a user