예제 #1
0
    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)
예제 #2
0
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
예제 #3
0
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)"])

    # scale the input speed to between 0 (stop) and 255 (full speed)
예제 #4
0
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)
예제 #5
0
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)"])

    # scale the input speed to between 0 (stop) and 255 (full speed)
    # these values were chosen by hand after inspecting the input data
    rider1Speed = 255 - (50 + inputDataRider1Speed * 8)
    rider2Speed = 255 - (50 + inputDataRider2Speed * 8)
예제 #6
0
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)