On this page I've quickly detailed the python script I use to drive a USB Robot ARM from my Raspberry Pi using a PlayStation 3 controller. I got the ARM from Maplins in the UK (Code:A37JN) and its a OWI EDGE 535 Robotic kit.
Most of the tools required to control the Robot ARM from a Raspberry Pi come pre-installed on the latest images, however you will need to install PyUSB to send commands to the ARM. With the PyUSB module installed and a PS3 controller attached its just a simple case of running the following script to control its movements.
The analogue sticks control the ARM movement, with the R1/R2 buttons moving the wrist and the X and Circle keys operating the gripper.
#!/usr/bin/env python
import pygame
import usb.core
import time
pygame.init()
# Wait for a joystick
while pygame.joystick.get_count() == 0:
print 'waiting for joystick count = %i' % pygame.joystick.get_count()
time.sleep(10)
pygame.joystick.quit()
pygame.joystick.init()
j = pygame.joystick.Joystick(0)
j.init()
print 'Initialized Joystick : %s' % j.get_name()
armFound = False
while not armFound:
dev = usb.core.find(idVendor=0x1267, idProduct=0x0000)
if dev is None:
print 'Arm not found. Waiting'
time.sleep(10)
else:
armFound = True
#this arm should just have one configuration...
dev.set_configuration()
# How far to move the JoyStick before it has an effect (0.60 = 60%)
threshold = 0.60
# Key mappings
PS3_BUTTON_SELECT = 0
PS3_AXIS_LEFT_HORIZONTAL = 0
PS3_AXIS_LEFT_VERTICAL = 1
PS3_AXIS_RIGHT_HORIZONTAL = 2
PS3_AXIS_RIGHT_VERTICAL = 3
PS3_AXIS_X = 17
PS3_AXIS_CIRCLE = 18
PS3_AXIS_R1 = 15
PS3_AXIS_R2 = 13
# Robot Arm defaults
command = (0,0,0)
lc = 0
shoulder = 0
base = 0
elbow = 0
wristup = 0
wristdown = 0
grip_open = 0
grip_close = 0
grip_command = 0
wrist_command = 0
shoulder_command = 0
base_command = 0
elbow_command = 0
# ARM control related stuff
def setcommand(axis_val):
if axis_val > threshold:
return 1
elif axis_val < -threshold:
return 2
elif abs(axis_val) < threshold:
return 0
def buildcommand(shoulc,basec,elbowc,wristc,gripc,lightc):
byte1 = shoulc + elbowc + wristc + gripc
comm_bytes = (byte1, basec, lightc)
return comm_bytes
def processArm(event):
global command, lc, shoulder, base, elbow, wristup, wristdown, grip_open, grip_close, grip_command, wrist_command, shoulder_command, base_command, elbow_command
if event.type == pygame.JOYBUTTONDOWN:
if event.button == PS3_BUTTON_SELECT:
if lc == 0:
lc = 1
else:
lc = 0
elif event.type == pygame.JOYAXISMOTION:
if event.axis == PS3_AXIS_LEFT_VERTICAL:
shoulder = event.value
elif event.axis == PS3_AXIS_LEFT_HORIZONTAL:
base = event.value
elif event.axis == PS3_AXIS_RIGHT_VERTICAL:
elbow = event.value
elif event.axis == PS3_AXIS_R1:
wristup = event.value
elif event.axis == PS3_AXIS_R2:
wristdown = event.value
elif event.axis == PS3_AXIS_X:
grip_open = event.value
elif event.axis == PS3_AXIS_CIRCLE:
grip_close = event.value
# Are we opening or closing the gripper?
if grip_open> threshold:
grip_command = 1
elif grip_close> threshold:
grip_command = 2
else:
grip_command = 0
# And the same for the wrist, are we moving up or down?
if wristup > threshold:
wrist_command = 1*4
elif wristdown > threshold:
wrist_command = 2*4
else:
wrist_command = 0
shoulder_command = setcommand(shoulder)*64
base_command = setcommand(base)
elbow_command = setcommand(elbow)*16
# Work out what to send out to the robot
newcommand = buildcommand(shoulder_command,base_command,
elbow_command, wrist_command, grip_command,lc)
# If the command has changed, send out the new one
if newcommand != command:
dev.ctrl_transfer(0x40, 6, 0x100, 0, newcommand, 1000)
command = newcommand
try:
# Loop forwever
while True:
# Sleep so we don't eat up all the CPU time
time.sleep(0.1)
# read in events
events = pygame.event.get()
# and process them
for event in events:
processArm(event)
except KeyboardInterrupt:
j.quit()