-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added the core library files, the setup file and a simple example using a Tkinter window and keyboard bindings to control the arm.
- Loading branch information
1 parent
32deea4
commit a352f43
Showing
3 changed files
with
379 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,195 @@ | ||
#!/usr/bin/env python3 | ||
|
||
from usbroboarm import Arm | ||
import tkinter as tk | ||
from tkinter.scrolledtext import ScrolledText | ||
import time | ||
import os | ||
|
||
# to run program | ||
# go into command line in the correct folder | ||
# enter 'sudo python3 Keyboard.py' to run | ||
|
||
# this line changes a global setting to prevent the TK window | ||
# from queueing too many events, so when you stop pressing a key the arm will stop | ||
os.system("xset r off") | ||
|
||
class App(tk.Tk): | ||
def __init__(self): | ||
tk.Tk.__init__(self) | ||
self.title("Keyboard Control of Robot Arm") | ||
self.arm = Arm() | ||
## self.arm.command_timeout = 50 # if arm still timeout's then uncomment this line and increase value | ||
|
||
f = tk.Frame(self) | ||
f.pack(side="top", expand=True, fill="x") | ||
|
||
f1 = tk.Frame(f, bd=1, relief="sunken") | ||
f1.pack(side="left") | ||
|
||
tk.Label(f1, text="Function:") .grid(column=1, row=1, sticky="w") | ||
tk.Label(f1, text="Key:") .grid(column=2, row=1, sticky="w") | ||
|
||
tk.Label(f1, text="Base Left:") .grid(column=1, row=2, sticky="w") | ||
tk.Label(f1, text="Left") .grid(column=2, row=2, sticky="w") | ||
tk.Label(f1, text="Base Right:") .grid(column=1, row=3, sticky="w") | ||
tk.Label(f1, text="Right") .grid(column=2, row=3, sticky="w") | ||
tk.Label(f1, text="Shoulder Up:") .grid(column=1, row=4, sticky="w") | ||
tk.Label(f1, text="Up") .grid(column=2, row=4, sticky="w") | ||
tk.Label(f1, text="Shoulder Down:") .grid(column=1, row=5, sticky="w") | ||
tk.Label(f1, text="Down") .grid(column=2, row=5, sticky="w") | ||
|
||
f2 = tk.Frame(f, bd=1, relief="sunken") | ||
f2.pack(side="left") | ||
|
||
tk.Label(f2, text="Function:") .grid(column=3, row=1, sticky="w") | ||
tk.Label(f2, text="Key:") .grid(column=4, row=1, sticky="w") | ||
|
||
tk.Label(f2, text="Elbow Up:") .grid(column=3, row=2, sticky="w") | ||
tk.Label(f2, text="Home") .grid(column=4, row=2, sticky="w") | ||
tk.Label(f2, text="Elbow Down:") .grid(column=3, row=3, sticky="w") | ||
tk.Label(f2, text="End") .grid(column=4, row=3, sticky="w") | ||
tk.Label(f2, text="Wrist Up:") .grid(column=3, row=4, sticky="w") | ||
tk.Label(f2, text="Insert") .grid(column=4, row=4, sticky="w") | ||
tk.Label(f2, text="Wrist Down:") .grid(column=3, row=5, sticky="w") | ||
tk.Label(f2, text="Delete") .grid(column=4, row=5, sticky="w") | ||
|
||
f3 = tk.Frame(f, bd=1, relief="sunken") | ||
f3.pack(side="left", fill="y") | ||
|
||
tk.Label(f3, text="Function:") .grid(column=5, row=1, sticky="w") | ||
tk.Label(f3, text="Key:") .grid(column=6, row=1, sticky="w") | ||
|
||
tk.Label(f3, text="Grip Open:") .grid(column=5, row=2, sticky="w") | ||
tk.Label(f3, text="Page-Up") .grid(column=6, row=2, sticky="w") | ||
tk.Label(f3, text="Grip Close:") .grid(column=5, row=3, sticky="w") | ||
tk.Label(f3, text="Page-Down") .grid(column=6, row=3, sticky="w") | ||
tk.Label(f3, text="Toggle Light:") .grid(column=5, row=4, sticky="w") | ||
tk.Label(f3, text="L") .grid(column=6, row=4, sticky="w") | ||
|
||
self.c_window = ScrolledText(self, width=20, height=20) | ||
self.c_window.pack(side="top", expand=True, fill="both") | ||
|
||
self.count = 1 | ||
|
||
self.lit = False | ||
|
||
self.bind("<FocusOut>", self.stop_all) | ||
self.bind("<Escape>", self.stop_all) | ||
self.bind("<l>", self.toggle_light) | ||
self.bind("<KeyPress-Prior>", self.grip_open) # page up key | ||
self.bind("<KeyRelease-Prior>", self.grip_stop) # page up key | ||
self.bind("<KeyPress-Next>", self.grip_close) # page down key | ||
self.bind("<KeyRelease-Next>", self.grip_stop) # page down key | ||
|
||
self.bind("<KeyPress-Left>", self.base_left) | ||
self.bind("<KeyRelease-Left>", self.base_stop) | ||
self.bind("<KeyPress-Right>", self.base_right) | ||
self.bind("<KeyRelease-Right>", self.base_stop) | ||
|
||
self.bind("<KeyPress-Up>", self.shoulder_up) | ||
self.bind("<KeyRelease-Up>", self.shoulder_stop) | ||
self.bind("<KeyPress-Down>", self.shoulder_down) | ||
self.bind("<KeyRelease-Down>", self.shoulder_stop) | ||
|
||
self.bind("<KeyPress-Home>", self.elbow_up) | ||
self.bind("<KeyRelease-Home>", self.elbow_stop) | ||
self.bind("<KeyPress-End>", self.elbow_down) | ||
self.bind("<KeyRelease-End>", self.elbow_stop) | ||
|
||
self.bind("<KeyPress-Insert>", self.wrist_up) | ||
self.bind("<KeyRelease-Insert>", self.wrist_stop) | ||
self.bind("<KeyPress-Delete>", self.wrist_down) | ||
self.bind("<KeyRelease-Delete>", self.wrist_stop) | ||
|
||
def message(self, message): | ||
if (self.count == 1): | ||
pass | ||
else: | ||
self.c_window.insert("end", "\n") | ||
self.c_window.insert("end", str(self.count) + "\t" + message) | ||
self.c_window.see("end") | ||
self.count += 1 | ||
|
||
def stop_all(self, event=None): | ||
self.message("Stop All") | ||
self.arm.stop_moving() | ||
|
||
def base_left(self, event=None): | ||
self.message("Base Left") | ||
self.arm.base_left() | ||
|
||
def base_right(self, event=None): | ||
self.message("Base Right") | ||
self.arm.base_right() | ||
|
||
def base_stop(self, event=None): | ||
self.message("Base Stop") | ||
time.sleep(0.1) | ||
self.arm.stop_moving() | ||
|
||
def shoulder_up(self, event=None): | ||
self.message("Shoulder Up") | ||
self.arm.shoulder_up() | ||
|
||
def shoulder_down(self, event=None): | ||
self.message("Shoulder Down") | ||
self.arm.shoulder_down() | ||
|
||
def shoulder_stop(self, event=None): | ||
self.message("Shoulder Stop") | ||
time.sleep(0.1) | ||
self.arm.stop_moving() | ||
|
||
def elbow_up(self, event=None): | ||
self.message("Elbow Up") | ||
self.arm.elbow_up() | ||
|
||
def elbow_down(self, event=None): | ||
self.message("Elbow Down") | ||
self.arm.elbow_down() | ||
|
||
def elbow_stop(self, event=None): | ||
self.message("Elbow Stop") | ||
time.sleep(0.1) | ||
self.arm.stop_moving() | ||
|
||
def wrist_up(self, event=None): | ||
self.message("Wrist Up") | ||
self.arm.wrist_up() | ||
|
||
def wrist_down(self, event=None): | ||
self.message("Wrist Down") | ||
self.arm.wrist_down() | ||
|
||
def wrist_stop(self, event=None): | ||
self.message("Wrist Stop") | ||
time.sleep(0.1) | ||
self.arm.stop_moving() | ||
|
||
def grip_open(self, event=None): | ||
self.message("Grip Open") | ||
self.arm.grip_open() | ||
|
||
def grip_close(self, event=None): | ||
self.message("Grip Close") | ||
self.arm.grip_close() | ||
|
||
def grip_stop(self, event=None): | ||
self.message("Grip Stop") | ||
time.sleep(0.1) | ||
self.arm.stop_moving() | ||
|
||
def toggle_light(self, event=None): | ||
self.message("Toggle Light") | ||
if self.lit: | ||
self.arm.light_off() | ||
self.lit = False | ||
else: | ||
self.arm.light_on() | ||
self.lit = True | ||
|
||
if __name__ == "__main__": | ||
app = App() | ||
app.mainloop() | ||
os.system("xset r on") # change the queue setting back |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#!/usr/bin/env python3 | ||
|
||
from distutils.core import setup | ||
setup(name='usbroboarm', | ||
version='1.0', | ||
py_modules=['usbroboarm'], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
#!/usr/bin/env python3 | ||
|
||
#import the USB and Time librarys into Python | ||
import usb.core, usb.util, time | ||
|
||
class Arm(): | ||
def __init__(self): | ||
"""This class tries to take control of the robot arm and exposes several methods | ||
of moving it, the first method is timed (it will stop that movement when the time expires) | ||
this method is blocking i.e. it can only do one type of movement at once. | ||
the second method requires one call to start the movement and another call to stop the movement. | ||
if the arm is plugged in through a USB hub the communication delay may be longer, | ||
if you get lost of timeout errors try increasing the property command_timeout from 50""" | ||
self.arm = usb.core.find(idVendor=0x1267, idProduct=0x000) | ||
if not self.arm: | ||
raise ValueError("Arm not found") | ||
|
||
self.command_timeout = 50 | ||
|
||
# store the last sent command | ||
self.current_command = [0,0,0] | ||
# this allows us to "add" movements together | ||
# so instead of only going up and then right | ||
# both can be done at the same time | ||
|
||
def _send_command(self): | ||
"""internal command, do not use""" | ||
try: | ||
self.arm.ctrl_transfer(0x40,6,0x100,0,self.current_command,self.command_timeout) | ||
except usb.core.USBError: | ||
print("Timed Out") | ||
|
||
def _build_command(self, | ||
shoulder_down=None, | ||
shoulder_up=None, | ||
elbow_down=None, | ||
elbow_up=None, | ||
wrist_down=None, | ||
wrist_up=None, | ||
grip_open=None, | ||
grip_closed=None): | ||
"""internal command, do not use""" | ||
num = self.current_command[0] | ||
# get the current settings | ||
c_shoulder_down, rem = divmod(num, 128) | ||
c_shoulder_up, rem = divmod(rem, 64) | ||
c_elbow_down, rem = divmod(rem, 32) | ||
c_elbow_up, rem = divmod(rem, 16) | ||
c_wrist_down, rem = divmod(rem, 8) | ||
c_wrist_up, rem = divmod(rem, 4) | ||
c_grip_open, c_grip_closed = divmod(rem, 2) | ||
if shoulder_down: | ||
c_shoulder_down = shoulder_down | ||
if shoulder_up: | ||
c_shoulder_up = shoulder_up | ||
if elbow_down: | ||
c_elbow_down = elbow_down | ||
if elbow_up: | ||
c_elbow_up = elbow_up | ||
if wrist_down: | ||
c_wrist_down = wrist_down | ||
if wrist_up: | ||
c_wrist_up = wrist_up | ||
if grip_open: | ||
c_grip_open = grip_open | ||
if grip_closed: | ||
c_grip_closed = grip_closed | ||
self.current_command[0] = c_shoulder_down*128 + c_shoulder_up*64 + c_elbow_down*32 + c_elbow_up*16 + c_wrist_down*8 + c_wrist_up*4 + c_grip_open*2 + c_grip_closed | ||
|
||
def light_on(self, duration=None): | ||
self.current_command[2] = 1 | ||
self._send_command() | ||
if duration: | ||
time.sleep(duration) | ||
self.light_off() | ||
|
||
def light_off(self, duration=None): | ||
self.current_command[2] = 0 | ||
self._send_command() | ||
if duration: | ||
time.sleep(duration) | ||
self.light_on() | ||
|
||
def base_left(self, duration=None): | ||
self.current_command[1] = 2 | ||
self._send_command() | ||
if duration: | ||
time.sleep(duration) | ||
self.base_stop() | ||
|
||
def base_right(self, duration=None): | ||
self.current_command[1] = 1 | ||
self._send_command() | ||
if duration: | ||
time.sleep(duration) | ||
self.base_stop() | ||
|
||
def base_stop(self): | ||
self.current_command[1] = 0 | ||
self._send_command() | ||
|
||
def grip_open(self, duration=None): | ||
self._build_command(grip_open=1, grip_closed=0) | ||
self._send_command() | ||
if duration: | ||
time.sleep(duration) | ||
self.grip_stop() | ||
|
||
def grip_close(self, duration=None): | ||
self._build_command(grip_open=0, grip_closed=1) | ||
self._send_command() | ||
if duration: | ||
time.sleep(duration) | ||
self.grip_stop() | ||
|
||
def grip_stop(self): | ||
self._build_command(grip_open=0, grip_closed=0) | ||
self._send_command() | ||
|
||
def wrist_up(self, duration=None): | ||
self._build_command(wrist_up=1, wrist_down=0) | ||
self._send_command() | ||
if duration: | ||
time.sleep(duration) | ||
self.wrist_stop() | ||
|
||
def wrist_down(self, duration=None): | ||
self._build_command(wrist_up=0, wrist_down=1) | ||
self._send_command() | ||
if duration: | ||
time.sleep(duration) | ||
self.wrist_stop() | ||
|
||
def wrist_stop(self): | ||
self._build_command(wrist_up=1, wrist_down=0) | ||
self._send_command() | ||
|
||
def elbow_up(self, duration=None): | ||
self._build_command(elbow_up=1, elbow_down=0) | ||
self._send_command() | ||
if duration: | ||
time.sleep(duration) | ||
self.elbow_stop() | ||
|
||
def elbow_down(self, duration=None): | ||
self._build_command(elbow_up=0, elbow_down=1) | ||
self._send_command() | ||
if duration: | ||
time.sleep(duration) | ||
self.elbow_stop() | ||
|
||
def elbow_stop(self): | ||
self._build_command(elbow_up=0, elbow_down=0) | ||
self._send_command() | ||
|
||
def shoulder_up(self, duration=None): | ||
self._build_command(shoulder_up=1, shoulder_down=0) | ||
self._send_command() | ||
if duration: | ||
time.sleep(duration) | ||
self.shoulder_stop() | ||
|
||
def shoulder_down(self, duration=None): | ||
self._build_command(shoulder_up=0, shoulder_down=1) | ||
self._send_command() | ||
if duration: | ||
time.sleep(duration) | ||
self.shoulder_stop() | ||
|
||
def shoulder_stop(self): | ||
self._build_command(shoulder_up=0, shoulder_down=0) | ||
self._send_command() | ||
|
||
def stop_moving(self): | ||
self.current_command[0] = 0 | ||
self.current_command[1] = 0 | ||
self._send_command() |