diff --git a/App/JS/Resources/CurrentEmuBotCode2/__pycache__/basic_classes.cpython-35.pyc b/App/JS/Resources/CurrentEmuBotCode2/__pycache__/basic_classes.cpython-35.pyc new file mode 100644 index 0000000..579b521 Binary files /dev/null and b/App/JS/Resources/CurrentEmuBotCode2/__pycache__/basic_classes.cpython-35.pyc differ diff --git a/App/JS/Resources/CurrentEmuBotCode2/__pycache__/connect.cpython-35.pyc b/App/JS/Resources/CurrentEmuBotCode2/__pycache__/connect.cpython-35.pyc new file mode 100644 index 0000000..fea2bca Binary files /dev/null and b/App/JS/Resources/CurrentEmuBotCode2/__pycache__/connect.cpython-35.pyc differ diff --git a/App/JS/Resources/CurrentEmuBotCode2/__pycache__/constants.cpython-35.pyc b/App/JS/Resources/CurrentEmuBotCode2/__pycache__/constants.cpython-35.pyc new file mode 100644 index 0000000..b496ebe Binary files /dev/null and b/App/JS/Resources/CurrentEmuBotCode2/__pycache__/constants.cpython-35.pyc differ diff --git a/App/JS/Resources/CurrentEmuBotCode2/__pycache__/controller.cpython-35.pyc b/App/JS/Resources/CurrentEmuBotCode2/__pycache__/controller.cpython-35.pyc new file mode 100644 index 0000000..d4c8dd9 Binary files /dev/null and b/App/JS/Resources/CurrentEmuBotCode2/__pycache__/controller.cpython-35.pyc differ diff --git a/App/JS/Resources/CurrentEmuBotCode2/__pycache__/wheel_arm_class.cpython-35.pyc b/App/JS/Resources/CurrentEmuBotCode2/__pycache__/wheel_arm_class.cpython-35.pyc new file mode 100644 index 0000000..c323544 Binary files /dev/null and b/App/JS/Resources/CurrentEmuBotCode2/__pycache__/wheel_arm_class.cpython-35.pyc differ diff --git a/App/JS/Resources/CurrentEmuBotCode2/basic_classes.py b/App/JS/Resources/CurrentEmuBotCode2/basic_classes.py new file mode 100644 index 0000000..3865488 --- /dev/null +++ b/App/JS/Resources/CurrentEmuBotCode2/basic_classes.py @@ -0,0 +1,93 @@ +""" Basic classes to be used by more advanced classes in wheel_arm_class.py """ + +import threading +import time +import connect + +class Joint(threading.Thread): + """ A Joint class representing a moving node on parts of the emubot """ + + def __init__(self, identity, position): + """ __init__(identity, position): parameters represent identification and position """ + threading.Thread.__init__(self) + self.direction = "neutral" + self.id = identity + self.position = position + self.move_joint(self.position, 900) + + def run(self): + """ Step through a sequence of moves """ + while self.direction != "": + if self.direction == "decrease": + if self.position > 200: + self.position -= 15 + elif self.direction == "increase": + if self.position < 800: + self.position += 15 + if self.direction != "neutral": + self.move_joint(self.position, 900) + time.sleep(0.1) + + def move_joint(self, position, speed): + """ Move the joint """ + output = '' + + if self.id < 10: + output += '0' + str(self.id) + else: + output += str(self.id) + + for _ in range(4 - len(str(position))): + output += '0' + + output += str(position) + + for _ in range(4 - len(str(speed))): + output += '0' + + output += str(position) + + output += '\n' + connect.SOCKET.sendall(bytes(output, 'utf-8')) + +class Wheel(object): + """ A Wheel class representing a wheel of the emubot """ + + def __init__(self, identity): + """ Wheel.__init__(ID): parameters - the ID of the wheel """ + self.id = str(identity) + self.direction = "none" + self.speed = 0 + + def move_wheel(self, speed): + """ Move the wheel """ + self.speed = speed + output = '0' + self.id + + if self.speed < 11 and self.speed > -11: + self.speed = 0 + elif self.speed < 0: + output += '-' + self.speed = self.speed*-1 + + for _ in range(4 - len(str(self.speed))): + output += '0' + + output += str(self.speed) + connect.SOCKET.sendall(bytes(output+"\n", 'utf-8')) + +class Switch(object): + """ A Switch class representing a switch on the emubot """ + + def __init__(self): + """ Switch.__init__(): initialise variables """ + self.on = True + + def change_status(): + """ Change the status of the switch """ + if self.on: + connect.SOCKET.sendall(bytes("OFF\n", "utf-8")) + self.on = False + else: + connect.SOCKET.sendall(bytes("ON\n", "utf-8")) + self.on = True diff --git a/App/JS/Resources/CurrentEmuBotCode2/client.py b/App/JS/Resources/CurrentEmuBotCode2/client.py new file mode 100644 index 0000000..5ce9320 --- /dev/null +++ b/App/JS/Resources/CurrentEmuBotCode2/client.py @@ -0,0 +1,160 @@ +""" The movement client for the emubot """ + +import basic_classes +import constants +import controller +import wheel_arm_class + +LEFT_MOVEMENT = 0 +RIGHT_MOVEMENT = 0 +FORWARDS_MOVEMENT = 0 + +LOCAL_SWITCH_ON = True +BACKWARDS_L = 1 +BACKWARDS_R = 1 + +ARM = wheel_arm_class.Arm([5, 6, 7]) +WHEEL_L1 = basic_classes.Wheel(1) +WHEEL_R2 = basic_classes.Wheel(2) +WHEEL_L3 = basic_classes.Wheel(3) +WHEEL_R4 = basic_classes.Wheel(4) + +def move_left_wheels(speed): + """ Move the wheels on the left side of the emubot """ + if speed == 0: + WHEEL_L1.move_wheel(0) + WHEEL_L3.move_wheel(0) + else: + WHEEL_L1.move_wheel(speed) + WHEEL_L3.move_wheel(speed) + +def move_right_wheels(speed): + """ Move the wheels on the right side of the emubot """ + if speed == 0: + WHEEL_R2.move_wheel(0) + WHEEL_R4.move_wheel(0) + else: + WHEEL_R2.move_wheel(speed) + WHEEL_R4.move_wheel(speed) + +print("Event loop starting...") + +for event in controller.gamepad.read_loop(): + try: + event_code = event.code + event_value = event.value + + if event_code != 0: + if event_code == constants.LEFT_TRG: + if LEFT_MOVEMENT == 3 or event_value <= 0: + if event_value > 0: + move_left_wheels(event_value * 4 * BACKWARDS_L) + else: + move_left_wheels(0) + LEFT_MOVEMENT = 1 + else: + LEFT_MOVEMENT = LEFT_MOVEMENT + 1 + + elif event_code == constants.RIGHT_TRG: + if RIGHT_MOVEMENT == 3 or event_value <= 0: + if event_value > 0: + move_right_wheels(-(event_value * 4 * BACKWARDS_R)) + else: + move_right_wheels(0) + RIGHT_MOVEMENT = 1 + else: + RIGHT_MOVEMENT = RIGHT_MOVEMENT + 1 + + elif event_code == constants.LB: + if event_value == 1: + if BACKWARDS_L > 0: + BACKWARDS_L = -1 + else: + BACKWARDS_L = 1 + + elif event_code == constants.RB: + if event_value == 1: + if BACKWARDS_R > 0: + BACKWARDS_R = -1 + else: + BACKWARDS_R = 1 + + elif event_code == constants.LHORIZ: + if FORWARDS_MOVEMENT == 3 or event_value <= 0: + if event_value > 0: + move_left_wheels(event_value / 40) + move_right_wheels(event_value / 40) + elif event_value < 0: + move_left_wheels(event_value / 40) + move_right_wheels(event_value / 40) + else: + move_left_wheels(0) + move_right_wheels(0) + FORWARDS_MOVEMENT = 1 + + else: + FORWARDS_MOVEMENT = FORWARDS_MOVEMENT + 1 + + elif event_code == constants.LVERT: + move_left_wheels(-(event_value / 40)) + move_right_wheels((event_value / 40)) + + elif event_code == constants.D_PAD_HORIZONTAL: + if event_value == 1: + ARM.move_pan(direction="increase") + elif event_value == -1: + ARM.move_pan(direction="decrease") + elif event_value == 0: + ARM.move_pan(direction="neutral") + + elif event_code == constants.D_PAD_VERTICAL: + if event_value == -1: + ARM.move_tilt(direction="increase") + elif event_value == 1: + ARM.move_tilt(direction="decrease") + elif event_value == 0: + ARM.move_tilt(direction="neutral") + + elif event_code == constants.Y: + if event_value == 1: + ARM.move_shoulder(direction="increase") + elif event_value == 0: + ARM.move_shoulder(direction="neutral") + + elif event_code == constants.A: + if event_value == 1: + ARM.move_shoulder(direction="decrease") + elif event_value == 0: + ARM.move_shoulder(direction="neutral") + + elif event_code == constants.X: + ARM.move_arm_set_position(shoulder_pos=512, tilt_pos=200, pan_pos=512) + + elif event_code == constants.B: + if LOCAL_SWITCH_ON and event_value != 0: + LOCAL_SWITCH_ON = False + print("OFF") + + elif event_value != 0: + LOCAL_SWITCH_ON = True + print("ON") + + elif event_code == constants.START: + # Reset all servos to original positions + ARM.reset() + WHEEL_L1.move_wheel(0) + WHEEL_L3.move_wheel(0) + WHEEL_R2.move_wheel(0) + WHEEL_R4.move_wheel(0) + + elif event_code == constants.BACK: + WHEEL_L1.move_wheel(0) + WHEEL_L3.move_wheel(0) + WHEEL_R2.move_wheel(0) + WHEEL_R4.move_wheel(0) + + else: + print("Unidentified Event:", event) + + except BrokenPipeError as error: + print(error) diff --git a/App/JS/Resources/CurrentEmuBotCode2/connect.py b/App/JS/Resources/CurrentEmuBotCode2/connect.py new file mode 100644 index 0000000..83637fd --- /dev/null +++ b/App/JS/Resources/CurrentEmuBotCode2/connect.py @@ -0,0 +1,20 @@ +""" Establishes the connection between the input device and the emubot """ + +print("connect setup") +import socket + +HOST, PORT = "192.168.100.1", 9999 #"169.254.44.240", 9999 +SOCKET = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +print("trying to establish a connection") + +try: + SOCKET.connect((HOST, PORT)) + print("connect ready") +except: + print(""" + CONNECTION FAILED.") + have you run the code on the raspberry pi? + P.S. dont break the pi please + """) + +print(SOCKET) diff --git a/App/JS/Resources/CurrentEmuBotCode2/constants.py b/App/JS/Resources/CurrentEmuBotCode2/constants.py new file mode 100644 index 0000000..3d0e919 --- /dev/null +++ b/App/JS/Resources/CurrentEmuBotCode2/constants.py @@ -0,0 +1,45 @@ +""" Constants module for this directory """ + +# Event Constants +LEFT_TRG = 2 +RIGHT_TRG = 5 +RB = 311 +LB = 310 +LCLICK = 317 +RCLICK = 318 +RVERT = 4 +RHORIZ = 3 +LVERT = 1 +LHORIZ = 0 +START = 315 +BACK = 314 +A = 304 +B = 305 +Y = 308 +X = 307 +D_PAD_VERTICAL = 17 +D_PAD_HORIZONTAL = 16 + +# Shoulder Direction +INCREASE = 1 +DECREASE = 2 +NEUTRAL = 3 +NOTHING = 0 + +# Switches +SWITCHON = 1 +SWITCHOFF = 0 + +# Arm Movement Divisor +MOVEMENT_SCALING = 4000 + +# Wheel and Arm Identifcations +HAND = 7 +ARM = 6 +SHOULDER = 5 + +# From the back view of the robot: +FRONT_LEFT_WHEEL = 1 +FRONT_RIGHT_WHEEL = 2 +BACK_LEFT_WHEEL = 3 +BACK_RIGHT_WHEEL = 4 diff --git a/App/JS/Resources/CurrentEmuBotCode2/controller.py b/App/JS/Resources/CurrentEmuBotCode2/controller.py new file mode 100644 index 0000000..a81599f --- /dev/null +++ b/App/JS/Resources/CurrentEmuBotCode2/controller.py @@ -0,0 +1,22 @@ +""" Initialises the input source by which the emubot is controlled """ + +import evdev + +devices = [evdev.InputDevice(input_source) for input_source in evdev.list_devices()] + +controllers = {"Logitech Gamepad F310", + "Logitech Gamepad F710", + "Microsoft X-Box 360 pad", + "Logitech Logitech Cordless RumblePad 2", + "Logitech Logitech Dual Action"} + +gamepad = None +for i in devices: + if i.name in controllers: + gamepad = i + break + +if gamepad is None: + raise TypeError("Variable 'gamepad' is None") + +print("Gamepad is:", gamepad) diff --git a/App/JS/Resources/CurrentEmuBotCode2/switch.py b/App/JS/Resources/CurrentEmuBotCode2/switch.py new file mode 100644 index 0000000..317a982 --- /dev/null +++ b/App/JS/Resources/CurrentEmuBotCode2/switch.py @@ -0,0 +1,13 @@ +""" A module defining a function to change the state of SOCKET """ + +import connect +import constants + +def switch(state): + """ Invert the state of SOCKET """ + if state == constants.SWITCHON: + connect.SOCKET.sendall(bytes("OFF\n", "utf-8")) + return constants.SWITCHOFF + + connect.SOCKET.sendall(bytes("ON\n", "utf-8")) + return constants.SWITCHON diff --git a/App/JS/Resources/CurrentEmuBotCode2/wheel_arm_class.py b/App/JS/Resources/CurrentEmuBotCode2/wheel_arm_class.py new file mode 100644 index 0000000..771cd86 --- /dev/null +++ b/App/JS/Resources/CurrentEmuBotCode2/wheel_arm_class.py @@ -0,0 +1,100 @@ +""" Complex classes representing different parts of the emubot """ + +import basic_classes + +print("Classes setup") + +class Arm(object): + """ Represents an arn of the emubot """ + + def __init__(self, identities): + """ + Arm.__init__(identities): parses an array with the identities of the: [shoulder, tilt, pan] + Initialises the joints within the arm, and starts their threading + """ + + self.shoulder = basic_classes.Joint(identities[0], 200) + self.tilt = basic_classes.Joint(identities[1], 200) + self.pan = basic_classes.Joint(identities[2], 512) + + self.shoulder.start() + self.tilt.start() + self.pan.start() + + def move_shoulder(self, position=None, direction=None): + """ Move the shoulder of the arm """ + self.shoulder.direction = direction + + def move_tilt(self, position=None, direction=None): + """ Tilt the arm """ + self.tilt.direction = direction + + def move_pan(self, position=None, direction=None): + """ Pan the arm """ + self.pan.direction = direction + + def move_arm_set_position(self, shoulder_pos=None, tilt_pos=None, pan_pos=None): + """ Manually set the position of the arm """ + if shoulder_pos: + self.shoulder.position = shoulder_pos + if tilt_pos: + self.tilt.position = tilt_pos + if pan_pos: + self.pan.position = pan_pos + + def reset(self): + """ Revert the arm to its initial position """ + self.shoulder.position = 200 + self.tilt.position = 200 + self.pan.position = 512 + + self.shoulder.move_joint(self.shoulder.position, 900) + self.tilt.move_joint(self.tilt.position, 900) + self.pan.move_joint(self.pan.position, 900) + + def print_angles(self): + """ Print the position, tilt and pan of the arm """ + print('The shoulder is at position:', self.shoulder.position) + print('The Tilt is at position:', self.tilt.position) + print('The Pan is at position:', self.pan.position) + +print('Arm Class Defined') + +class Flipper(object): + """ Represents a flipper on the emubot """ + + def __init__(self, wheel_id, joint_id): + """ + Flipper.__init__(wheel_id, joint_id): IDs of the servo that controls the flipper + Initialises the joints within the flipper + """ + + self.joint_id = joint_id + self.wheel = basic_classes.Wheel(wheel_id) + + self.joint_init() + self.joint.start() + + def move_flipper(self, direction=None): + """ Move the flipper """ + self.joint.direction = direction + + def joint_init(self): + """ Initialise the flipper's joints """ + if self.joint_id in [5, 8]: + self.joint = basic_classes.Joint(self.joint_id, 200) + elif self.joint_id in [6, 7]: + self.joint = basic_classes.Joint(self.joint_id, 800) + + def reset(self): + """ Revert the flipper to its original position """ + self.wheel.direction = 'none' + self.wheel.move_wheel() + self.joint_init() + + def move_wheel(self, direction=None, speed=0): + """ Move the wheel of the flipper """ + self.wheel.speed = speed + self.wheel.move_wheel() + +print("Flipper Class Defined") diff --git a/App/JS/client.js b/App/JS/client.js deleted file mode 100644 index 43392c3..0000000 --- a/App/JS/client.js +++ /dev/null @@ -1,60 +0,0 @@ -var net = require('net'); -var client = new net.Socket(); - -function terminateConnection(connection) { - connection.write("01-0000"); - connection.write("02-0000"); - connection.write("03-0000"); - connection.write("04-0000"); -} - -function axisValue(dynamixel, axis) { - var gamepad = navigator.getGamepads()[0]; - var val = Math.round((gamepad.axes[axis]+1) * 512); - //if (dynamixel == 1 || dynamixel == 3) { - // val -= 1024 - //} - var out = ""; - if (val < 10) { - out += "000"; - out += val; - } else if (val < 100) { - out += "00"; - out += val; - } else if (val < 1000) { - out += "0"; - out += val; - } else { - out += val; - } - return out -} -client.connect(9999, '192.168.100.1', function() { - window.addEventListener("gamepadconnected", function(event) { - setInterval(function() { - client.write('01-' + axisValue(1, 3)); - }, 30); - setInterval(function() { - client.write('02-' + axisValue(2, 1)); - }, 30); - setInterval(function() { - client.write('03-' + axisValue(3, 3)); - }, 30); - setInterval(function() { - client.write('04-' + axisValue(4, 1)); - }, 30); - setTimeout(function(){ - terminateConnection(client) - }, 1000) - }); -}); - -client.on('close', function(){ - console.warn("Client terminated connection!") -}) -client.on('end', function(){ - console.warn("Server terminated connection!") -}) -client.on('error', function(){ - console.warn("Connection to server terminated unexpectedly!") -}) diff --git a/App/JS/executeShellCommand.js b/App/JS/executeShellCommand.js new file mode 100644 index 0000000..569a2a9 --- /dev/null +++ b/App/JS/executeShellCommand.js @@ -0,0 +1,15 @@ +var exec = require('child_process').exec; + +function execute(command) { + command = String(command); + + exec(command, function (error, stdout, stderr) { + console.log('stdout: ' + stdout); + console.log('stderr: ' + stderr); + if (error !== null) { + console.log('exec error: ' + error); + } + }); +}; + +module.exports = { execute }; diff --git a/App/control.html b/App/control.html index ded0420..5ccffd7 100644 --- a/App/control.html +++ b/App/control.html @@ -6,7 +6,10 @@ - +