def startWebSocketClient(self): self.cannybot = CannybotClient() # Connects to the default Cannybot self.cannybot.registerReceiveCallback(self.send2scratch) # If there's any trouble just exit, the service daemon will restart us self.cannybot.registerErrorCallback(self.stop) self.cannybot.registerClosedCallback(self.stop)
def bleInit(self): if sys.platform == 'darwin': return self.ble1 = CannybotClient(botId=0) self.ble2 = CannybotClient(botId=1) self.ble1.registerReceiveCallback(self.bleRacer1ReceviedData) self.ble2.registerReceiveCallback(self.bleRacer2ReceviedData)
def startWebSocketClient(self): self.cannybot = CannybotClient() # Connects to the default Cannybot self.cannybot.registerReceiveCallback(self.send2scratch) # If there's any trouble just exit, the service daemon will restart us self.cannybot.registerErrorCallback(self.stop) self.cannybot.registerClosedCallback(self.stop)
import sys import os import csv from time import sleep from sys import stdin from cannybots.clients.wsclient import CannybotClient def dataReceived(message): print "Received: " + message cannybot = CannybotClient() # Connects to the first available Cannybot cannybot.registerReceiveCallback(dataReceived) sleep(2) # wait a bit for connection setup while 1: userinput = stdin.readline() if len(userinput) > 0: cannybot.send(format(ord(userinput[0]), '02X'))
class ScratchAgent: def __init__(self): log( "Cannybots Scratch Agent starting...") self.keepRunning = True self.scratchInterface = None self.cannybot = None def startWebSocketClient(self): self.cannybot = CannybotClient() # Connects to the default Cannybot self.cannybot.registerReceiveCallback(self.send2scratch) # If there's any trouble just exit, the service daemon will restart us self.cannybot.registerErrorCallback(self.stop) self.cannybot.registerClosedCallback(self.stop) def startScratchClient(self): self.scratchInterface = scratch.Scratch() self.scratchInterface.connect() def send2scratch(self, msg): if self.scratchInterface: log("sending to scratch: " + str(msg)) try: self.scratchInterface.broadcast(msg) except scratch.ScratchConnectionError as sce: log( "ERROR: (ScratchConnection) " + sce.message) self.keepRunning = False except Exception as err: log( "ERROR: (General, whilst sending to Scatch) " + err.message) self.keepRunning = False else: print "WARN: Scratch not yet initialised" def send2cannybot(self, message): self.cannybot.send(format(ord(message),'02X')) # TODO: make this configurable and general purpose def processMessage(self, message): commands = { 'MoveForward' : self.maze_forward, 'TurnRight' : self.maze_right, 'TurnLeft' : self.maze_left, 'Spin' : self.maze_spin, 'Stop' : self.maze_stop } command = message[1] #log( "Command: " + command) if command in commands: commands[command](message); else: log( "WARN: Unrecognised message: {}".format(message)) # Mazing def maze_forward(self, message): self.send2cannybot('f') def maze_right(self, message): self.send2cannybot('r') def maze_left(self, message): self.send2cannybot('l') def maze_spin(self, message): self.send2cannybot('p') def maze_stop(self, message): self.send2cannybot('s') #motor commands #led and other sensor commands def isConnected(self): wsOK = self.cannybot.isConnected() scratchOK = self.scratchInterface.connected = True if (wsOK and scratchOK and self.keepRunning): return True else: if (not scratchOK): log( "Not connected to scratch") if (not wsOK): log( "Not connected to webocket API") return False def connect(self): self.startScratchClient(); self.startWebSocketClient(); def run(self): self.workerThread = Thread(target=self._scratch_message_worker) self.workerThread.daemon = True self.workerThread.name = 'ScratchMsgWorker' self.workerThread.start() def _scratch_message_worker(self): try: while self.keepRunning: for msg in self.listen(): if msg[0] == 'broadcast': log( "From scratch (broadcast): " + str(msg)) self.processMessage(msg) elif msg[0] == 'sensor-update': log( "From scratch (sensor): " + str(msg)) except scratch.ScratchError as se: log( "ERROR: MsgWorker (Scratch) " + se.message) except StopIteration as si: log( "ERROR: MsgWorker (MsgProc) " + si.message) except Exception as err: log( "ERROR: MsgWorker (General) " + err.message) self.keepRunning = False def listen(self): while True: try: yield self.scratchInterface.receive() except scratch.ScratchError: raise StopIteration def start(self): try: self.connect() self.run() while True: sleep(CONNECTION_CHECK_DELAY) if not self.isConnected(): break except scratch.ScratchError as se: log ("ERROR: Main (Scratch) " + se.message) except Exception as err: log( "ERROR: Main (General) " + err.message) def stop(self): log( "Cannybots Scratch Agent exiting...") self.keepRunning=False;
class ScratchAgent: def __init__(self): log("Cannybots Scratch Agent v{} starting...".format(VERSION)) self.keepRunning = True self.scratchInterface = None self.cannybot = None def startWebSocketClient(self): self.cannybot = CannybotClient() # Connects to the default Cannybot self.cannybot.registerReceiveCallback(self.processCannybotEvent) # If there's any trouble just exit, the service daemon will restart us self.cannybot.registerErrorCallback(self.stop) self.cannybot.registerClosedCallback(self.stop) self.joypad = JoypadClient(self.cannybot) def startScratchClient(self): self.scratchInterface = scratch.Scratch() self.scratchInterface.connect() def send2scratch(self, msg): if self.scratchInterface: log("sending to scratch: " + str(msg)) try: self.scratchInterface.broadcast(msg) except scratch.ScratchConnectionError as sce: log("ERROR: (ScratchConnection) " + sce.message) self.keepRunning = False except Exception as err: log("ERROR: (General, whilst sending to Scatch) " + err.message) self.keepRunning = False else: print "WARN: Scratch not yet initialised" def send2cannybot(self, message): self.cannybot.send(format(ord(message), '02X')) # TODO: make this configurable and general purpose def processScratchSensorUpdate(self, message): log("processScratchSensorUpdate: {}".format(message)) for sensor, value in message[1].iteritems(): log("INFO: processScratchSensorUpdate {} = {}".format( sensor, value)) if sensor == "CannybotSpeed": self.joypad.setSpeed(value) # TODO: make this configurable and general purpose def processScratchBroadcast(self, message): commands = { 'MoveForward': self.maze_forward, 'TurnRight': self.maze_right, 'TurnLeft': self.maze_left, 'Spin': self.maze_spin, 'Stop': self.maze_stop } command = message[1] #log( "Command: " + command) if command in commands: commands[command](message) else: log("WARN: Unrecognised broadcast: {}".format(message)) # TODO: make this configurable and general purpose def processCannybotEvent(self, message): log("cannybot event {}".format(message)) eventTextMappings = { 'RGB:R': "Red", 'RGB:G': "Green", 'RGB:B': "Blue", 'RGB:Y': "Yellow", 'LINE:N': "OffTheLine", 'LINE:Y': "OnTheLine", } eventText = message #log( "Command: " + command) if eventText in eventTextMappings: eventText = eventTextMappings[eventText] self.send2scratch(eventText) # Mazing def maze_forward(self, message): self.send2cannybot('f') def maze_right(self, message): self.send2cannybot('r') def maze_left(self, message): self.send2cannybot('l') def maze_spin(self, message): self.send2cannybot('p') def maze_stop(self, message): self.send2cannybot('s') #motor commands #led and other sensor commands def isConnected(self): wsOK = self.cannybot.isConnected() scratchOK = self.scratchInterface.connected = True if (wsOK and scratchOK and self.keepRunning): return True else: if (not scratchOK): log("Not connected to scratch") if (not wsOK): log("Not connected to webocket API") return False def connect(self): self.startScratchClient() self.startWebSocketClient() def run(self): self.workerThread = Thread(target=self._scratch_message_worker) self.workerThread.daemon = True self.workerThread.name = 'ScratchMsgWorker' self.workerThread.start() def _scratch_message_worker(self): try: while self.keepRunning: for msg in self.listen(): if msg[0] == 'broadcast': log("From scratch (broadcast): " + str(msg)) self.processScratchBroadcast(msg) elif msg[0] == 'sensor-update': log("From scratch (sensor): " + str(msg)) self.processScratchSensorUpdate(msg) except scratch.ScratchError as se: log("ERROR: MsgWorker (Scratch) " + se.message) except StopIteration as si: log("ERROR: MsgWorker (MsgProc) " + si.message) except Exception as err: log("ERROR: MsgWorker (General) " + err.message) self.keepRunning = False def listen(self): while True: try: yield self.scratchInterface.receive() except scratch.ScratchError: raise StopIteration def start(self): try: self.connect() self.run() while True: sleep(CONNECTION_CHECK_DELAY) if not self.isConnected(): break except scratch.ScratchError as se: log("ERROR: Main (Scratch) " + se.message) except Exception as err: log("ERROR: Main (General) " + err.message) def stop(self): log("Cannybots Scratch Agent exiting...") self.keepRunning = False
import csv from time import sleep from cannybots.clients.wsclient import CannybotClient from cannybots.clients.joypad import JoypadClient SPEED_DURATION = 2 # Number of seconds to hold a speed for cannybot1 = CannybotClient( botId='2' ) # Connects to the default Cannybot configured in NodeRED (using a local WebSocket API) cannybot2 = CannybotClient(botId='3') sleep(2) rider1 = JoypadClient( cannybot1 ) # Creates a Joystick helper that can create and send joystick messages rider2 = JoypadClient(cannybot2) # Open a csv files that has rows of Speeds in # This uses the first row in the CSV for the column names (see the speeds.csv) input_file = csv.DictReader( open("Cycling Data for Cannybots.xlsx - Cyclists.csv")) for row in input_file: # Read the speed from column which has the title of 'Speed' in the current row inputDataRider1Speed = float(row["Rider One Speed (km/Hr)"]) inputDataRider2Speed = float(row["Rider Two Speed (km/Hr)"])
import sys import os import csv from time import sleep from sys import stdin from cannybots.clients.wsclient import CannybotClient def dataReceived(message): print "Received: " + message cannybot = CannybotClient() # Connects to the first available Cannybot cannybot.registerReceiveCallback(dataReceived) sleep(2) # wait a bit for connection setup while 1: userinput = stdin.readline() if len(userinput)>0: cannybot.send(format(ord(userinput[0]),'02X'))
import csv from time import sleep from cannybots.clients.wsclient import CannybotClient from cannybots.clients.joypad import JoypadClient SPEED_DURATION = 2 # Number of seconds to hold a speed for cannybot = CannybotClient() # Connects to the default Cannybot configured in NodeRED (using a local WebSocket API) joypad = JoypadClient(cannybot) # Creates a Joystick helper that can create and send joystick messages # Open a csv files that has rows of Speeds in # This uses the first row in the CSV for the column names (see the speeds.csv) input_file = csv.DictReader(open("speeds.csv")) for row in input_file: # Read the speed from column which has the title of 'Speed' in the current row inputDataSpeed = float(row["Speed"]) # scale the input speed to between 0 (stop) and 255 (full speed) # these values were chosen by hand after inspecting the input data cannybotSpeed = 50 + inputDataSpeed * 10 print "Input Data speed: {} => Cannybot speed: {}".format(inputDataSpeed, cannybotSpeed) # send the forward speed joypad.update(0, cannybotSpeed, 0, 0)
class RaceController(): """ RaceController """ def __init__(self): self.player1Stats = 0 self.player2Stats = 0 self.mainScoreBoard = 0 self.bleInit() self.lastUpdateTime = time.time() self.running = True self.display = Display(windowed=1, windowWidth=1280, windowHeight=800) self.screen = self.display.screen self.clock = pygame.time.Clock() self.appInit() def appInit(self): self.app = gui.App() c = gui.Container(align=0, valign=0) self.table = self.setupTable() c.add(self.table, 0, 0) self.app.init(c) def decreasePlayerSpeed(self, player): print "decreasePlayerSpeed:%d" % player def increasePlayerSpeed(self, player): print "increasePlayerSpeed:%d" % player if player == 1: self.mainScoreBoard.newTime("One", self.player1Stats.currentLapTime, ) else: self.mainScoreBoard.newTime("Two",self.player2Stats.currentLapTime) def resetBoard(self, value): self.mainScoreBoard.reset() self.player1Stats.reset() self.player2Stats.reset() def createIcon(self, imageFile, text, callback, value): e = Obj() e.image = pygame.image.load(imageFile) e.rect = pygame.Rect(0, 0, e.image.get_width(), e.image.get_height()) e.align = 0 btn = gui.Icon(text, style={'font': roboticaSmallFont, 'image': e.image}) btn.connect(gui.CLICK, callback, value) return btn def createImage(self, imageFile): e = Obj() e.image = pygame.image.load(imageFile) e.rect = pygame.Rect(0, 0, e.image.get_width(), e.image.get_height()) e.align = 0 e.style = {} print repr(e.style) return e def setupTable(self): fg = (0, 0, 0) self.player1Stats = PlayerTimes(1) self.player2Stats = PlayerTimes(2) self.mainScoreBoard = LapTimeScoreBoard() p1SlowBtn = self.createIcon(basedir+"/images/button.png", "slower", self.decreasePlayerSpeed, 1) p1FastBtn = self.createIcon(basedir+"/images/button.png", "faster", self.increasePlayerSpeed, 1) p2SlowBtn = self.createIcon(basedir+"/images/button.png", "slower", self.decreasePlayerSpeed, 2) p2FastBtn = self.createIcon(basedir+"/images/button.png", "faster", self.increasePlayerSpeed, 2) resetBtn = self.createIcon(basedir+"/images/button.png", "reset", self.resetBoard, 1) # Create the Table cells table = gui.Table(width=self.screen.get_width(), height=self.screen.get_height()) table.tr() table.td(gui.Label("")) table.td(gui.Label("")) table.td(gui.Image(basedir + "/images/cannybots_logo.png"), colspan=1, rowspan=1, align=0, valign=0) table.td(gui.Label("")) table.td(gui.Label("")) table.tr() table.td(gui.Label("Racer One", color=fg, style={'font': roboticaMediumFont}), colspan=2, rowspan=1, align=1, valign=-1) table.td(self.mainScoreBoard, colspan=1, rowspan=2) table.td(gui.Label("Racer Two", color=fg, style={'font': roboticaMediumFont}), colspan=2, rowspan=1, align=-1, valign=-1) table.tr() table.td(self.player1Stats, colspan=2, valign=-1) table.td(gui.Label("")) table.td(self.player2Stats, colspan=2, valign=-1) table.tr() table.td(p1SlowBtn, rowspan=1, align=-1) table.td(p1FastBtn, rowspan=1, align=1) table.td(resetBtn) table.td(p2SlowBtn, rowspan=1, align=-1) table.td(p2FastBtn, rowspan=1, align=1) table.tr() return table def handleEvents(self): for event in pygame.event.get(): if event.type == pygame.QUIT: self.running = 0 elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE: self.running = False else: self.app.event(event) def draw(self): self.screen.fill((255, 255, 255)) # self.screen.set_clip(self.mainScoreBoard.get_abs_rect()) # self.screen.set_clip() self.app.paint() pygame.display.flip() def update(self): pass #if self.player1Stats.timerStarted: # self.player1Stats.setCurrentLapTime(time.time() - self.player1Stats.startTime) #if self.player2Stats.timerStarted: # self.player2Stats.setCurrentLapTime(time.time() - self.player2Stats.startTime) def run(self): while self.running: self.handleEvents() self.update() self.draw() self.clock.tick(30) pygame.quit() def bleRacer1ReceviedData(self, message): print "p1: " + str (message) if not self.player1Stats: return if message.startswith("LAP_START"): print "Player1 Lap!" if self.player1Stats.timerStarted: self.player1Stats.setCurrentLapTime(time.time() - self.player1Stats.startTime) self.mainScoreBoard.newTime("One", self.player1Stats.currentLapTime) self.player1Stats.currentLapTime = 0 self.player1Stats.timerStarted=True self.player1Stats.startTime=time.time() def bleRacer2ReceviedData(self, message): print "p2: " + str (message) if not self.player2Stats: return if message.startswith("LAP_START"): print "Player2 Lap Start!" if self.player2Stats.timerStarted: self.player2Stats.setCurrentLapTime(time.time() - self.player2Stats.startTime) self.mainScoreBoard.newTime("Two", self.player2Stats.currentLapTime) self.player2Stats.currentLapTime = 0 self.player2Stats.timerStarted=True self.player2Stats.startTime=time.time() def bleInit(self): if sys.platform == 'darwin': return self.ble1 = CannybotClient(botId=0) self.ble2 = CannybotClient(botId=1) self.ble1.registerReceiveCallback(self.bleRacer1ReceviedData) self.ble2.registerReceiveCallback(self.bleRacer2ReceviedData)
import sys import os import csv from time import sleep from cannybots.clients.wsclient import CannybotClient from cannybots.clients.joypad import JoypadClient def dataReceived(message): print "Received: " + message cannybot = CannybotClient() # Connects to the first available Cannybot joypad = JoypadClient(cannybot) cannybot.registerReceiveCallback(dataReceived) sleep(2) # wait a bit for connection setup joypad.requestStatus() #for speed in range(-255 , 255): # print "Speed: " + str(speed) # joypad.update(speed, speed, 0, 0) # sleep(0.25) for speed in range(1,5): motorASpeed = speed*50 motorBSpeed = speed*50 joypad.update(motorASpeed, motorBSpeed, 0, 0) sleep(1)