26 Commits

Author SHA1 Message Date
b861a61f07 Merge branch 'main' of https://git.myitr.org/Jukebox/jukebox-software 2024-03-05 16:30:26 -06:00
925ceb4b5a Commented jupytr notebook 2024-03-05 16:30:19 -06:00
dd2559130d Commented jupytr notebook 2024-03-05 16:27:48 -06:00
1fa7654da5 removed temp file 2024-03-05 16:21:07 -06:00
051cc1d003 Merge branch 'main' of https://git.myitr.org/Jukebox/jukebox-software 2024-03-05 16:20:11 -06:00
e1af00e1db Inverse kinematics complete 2024-03-05 16:20:05 -06:00
af6ffe451d Fix get_specs 2024-03-01 19:26:47 -06:00
50bf835d13 Update parsing and stuff 2024-03-01 19:25:01 -06:00
fe5de4e54c Adjust datasheet parsing for meilisearch, add dockerfile 2024-02-17 23:08:21 -06:00
523915feb0 add partnum to parsing 2024-02-17 20:31:43 -06:00
b5b2a936c1 Switch to binary dependency 2024-02-17 20:25:51 -06:00
afd144bd32 FIx requirements.txt 2024-02-17 20:22:54 -06:00
eb221a5206 Create main runner app, with async multithreading 2024-02-17 20:21:42 -06:00
db7c8c4577 Add video abstraction class 2024-02-17 20:06:37 -06:00
21b1bf7992 Added system exit 2024-02-16 20:36:43 -06:00
d376dba67c Add keyboard control scripts, add websocket server 2024-02-08 12:35:30 -06:00
95631dbdbe Add LED array mapping, load base config for tabletop rings, and image/video player mode 2024-01-25 20:06:10 -06:00
9aef296763 More logging 2024-01-18 16:45:37 -06:00
2b287492de Make firefox start faster, verbose start 2024-01-18 16:41:57 -06:00
d2a4d93590 Working network test 2024-01-18 16:35:02 -06:00
58605dbe85 test server/client setup 2024-01-18 16:00:12 -06:00
7bf3276ce9 Add basic windows control system. Needs VM functional to continue 2024-01-17 20:14:20 -06:00
818688452b Add local loading page 2024-01-17 16:46:20 -06:00
01526524d4 Create main runner app, with async multithreading 2024-01-17 16:06:15 -06:00
33671683ea test rendering json in HTML table format 2024-01-17 09:23:06 -06:00
fad885c610 Add UR5 control test, datasheet JSON output 2024-01-16 17:27:55 -06:00
10 changed files with 783 additions and 81 deletions

11
Dockerfile Normal file
View File

@ -0,0 +1,11 @@
FROM python:latest
RUN apt-get update && apt-get install -y libgl1-mesa-glx ghostscript && apt-get clean && rm -rf /var/lib/apt/lists
COPY . .
#COPY config-server.yml config.yml
RUN pip3 install -r requirements.txt
CMD ["python3", "run.py"]
EXPOSE 5000
EXPOSE 8000
EXPOSE 9000

View File

@ -32,13 +32,13 @@ led:
ledstart: 288 ledstart: 288
ledend: 431 ledend: 431
mode: rgb mode: rgb
- universe: 1 - universe: 4
ip: 192.168.68.130 ip: 192.168.5.40
ledstart: 432 ledstart: 432
ledend: 575 ledend: 575
mode: rgb mode: rgb
- universe: 4 - universe: 1
ip: 192.168.68.131 ip: 192.168.5.4
ledstart: 576 ledstart: 576
ledend: 719 ledend: 719
mode: rgb mode: rgb

View File

@ -26,7 +26,7 @@ def check_internet(url='https://belden.com', timeout=5):
def query_search(partnum): def query_search(partnum, source):
"""token_url = "https://www.belden.com/coveo/rest/token?t=" + str(int(time.time())) """token_url = "https://www.belden.com/coveo/rest/token?t=" + str(int(time.time()))
with requests.get(token_url) as r: with requests.get(token_url) as r:
out = json.loads(r.content) out = json.loads(r.content)
@ -49,15 +49,50 @@ def query_search(partnum):
# Bash script uses some crazy json formatting that I could not figure out # Bash script uses some crazy json formatting that I could not figure out
# Despite the fact that I wrote it # Despite the fact that I wrote it
# So I'll just leave it, becuase it works. # So I'll just leave it, becuase it works.
if source == "Belden":
command = ["./query-search.sh", partnum]
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
if result.returncode != 0: # error
fprint("No results found in search database for " + partnum + ". No hi-res part image available.", result.stderr)
return False
else:
data_out = json.loads(result.stdout)
return data_out
elif source == "Alphawire":
alphaurl = "https://www.alphawire.com//sxa/search/results/?l=en&s={4A774076-6068-460C-9CC6-A2D8E85E407F}&itemid={BF82F58C-EFD9-4D8B-AE3E-097DD12CF7DA}&sig=&autoFireSearch=true&productpartnumber=*" + partnum + "*&v={B22CD56D-AB95-4048-8AA1-5BBDF2F2D17F}&p=10&e=0&o=ProductPartNumber%2CAscending"
r = requests.get(url=alphaurl)
data = r.json()
output = dict()
#print(data)
try:
if data["Count"] > 0:
print(data["Results"][0]["Url"])
result = data["Results"][0]
if result["Url"].split("/")[-1] == partnum:
#print(partnum)
print(result["Html"])
try:
imgidx = result["Html"].index("<img src=") + 10
imgidx2 = result["Html"].index("?", imgidx)
output["image"] = result["Html"][imgidx:imgidx2]
if output["image"].index("http") != 0:
output["image"] = ""
print("No cable image found.")
except:
print("No cable image found.")
command = ["./query-search.sh", partnum] dsidx = result["Html"].index("<a href=\"/disteAPI/") + 9
result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) dsidx2 = result["Html"].index(partnum, dsidx) + len(partnum)
if result.returncode != 0: # error output["datasheet"] = "https://www.alphawire.com" + result["Html"][dsidx:dsidx2]
fprint("No results found in search database for " + partnum + ". No hi-res part image available.", result.stderr) #"test".index()
print(output)
return output
except:
return False
return False return False
else:
data_out = json.loads(result.stdout)
return data_out
def touch(path): def touch(path):
with open(path, 'a'): with open(path, 'a'):
@ -126,7 +161,7 @@ def get_multi(partnums):
sys.exit() sys.exit()
def _download_image(url, output_dir): # Download datasheet with known URL def _download_image(url, output_dir): # Download image with known URL
global bartext global bartext
#fprint(url) #fprint(url)
@ -151,25 +186,31 @@ def get_multi(partnums):
os.remove(partnum + "/datasheet.pdf") os.remove(partnum + "/datasheet.pdf")
sys.exit() sys.exit()
def __use_cached_datasheet(partnum, path, output_dir): def __use_cached_datasheet(partnum, path, output_dir, dstype):
fprint("Using cached datasheet for " + partnum) fprint("Using cached datasheet for " + partnum)
bar.text = "Using cached datasheet for " + partnum bar.text = "Using cached datasheet for " + partnum
bar(skipped=True) bar(skipped=True)
fprint("Parsing Datasheet contents of " + partnum) fprint("Parsing Datasheet contents of " + partnum)
bar.text = "Parsing Datasheet contents of " + partnum + ".pdf..." bar.text = "Parsing Datasheet contents of " + partnum + ".pdf..."
read_datasheet.parse(path, output_dir) read_datasheet.parse(path, output_dir, partnum, dstype)
bar(skipped=False) bar(skipped=False)
def __downloaded_datasheet(partnum, path, output_dir): def __downloaded_datasheet(partnum, path, output_dir, dstype):
fprint("Downloaded " + path) fprint("Downloaded " + path)
bar.text = "Downloaded " + path bar.text = "Downloaded " + path
bar(skipped=False) bar(skipped=False)
fprint("Parsing Datasheet contents of " + partnum) fprint("Parsing Datasheet contents of " + partnum)
bar.text = "Parsing Datasheet contents of " + partnum + ".pdf..." bar.text = "Parsing Datasheet contents of " + partnum + ".pdf..."
read_datasheet.parse(path, output_dir) read_datasheet.parse(path, output_dir, partnum, dstype)
bar(skipped=False) bar(skipped=False)
for partnum in partnums: for fullpartnum in partnums:
if fullpartnum[0:2] == "BL": # catalog.belden.com entry\
partnum = fullpartnum[2:]
dstype = "Belden"
elif fullpartnum[0:2] == "AW":
partnum = fullpartnum[2:]
dstype = "Alphawire"
output_dir = "cables/" + partnum output_dir = "cables/" + partnum
path = output_dir + "/datasheet.pdf" path = output_dir + "/datasheet.pdf"
bartext = "Downloading files for part " + partnum bartext = "Downloading files for part " + partnum
@ -177,7 +218,7 @@ def get_multi(partnums):
# #
if (not os.path.exists(output_dir + "/found_part_hires")) or not (os.path.exists(path) and os.path.getsize(path) > 1): if (not os.path.exists(output_dir + "/found_part_hires")) or not (os.path.exists(path) and os.path.getsize(path) > 1):
# Use query # Use query
search_result = query_search(partnum.replace(" ", "")) search_result = query_search(partnum.replace(" ", ""), dstype)
# Try to use belden.com search # Try to use belden.com search
if search_result is not False: if search_result is not False:
# Download high resolution part image if available and needed # Download high resolution part image if available and needed
@ -190,17 +231,17 @@ def get_multi(partnums):
# Download datasheet from provided URL if needed # Download datasheet from provided URL if needed
if os.path.exists(path) and os.path.getsize(path) > 1: if os.path.exists(path) and os.path.getsize(path) > 1:
__use_cached_datasheet(partnum, path, output_dir) __use_cached_datasheet(partnum, path, output_dir, dstype)
elif _download_datasheet(search_result["datasheet"], output_dir) is not False: elif _download_datasheet(search_result["datasheet"], output_dir) is not False:
__downloaded_datasheet(partnum, path, output_dir) __downloaded_datasheet(partnum, path, output_dir, dstype)
elif os.path.exists(path) and os.path.getsize(path) > 1: elif os.path.exists(path) and os.path.getsize(path) > 1:
__use_cached_datasheet(partnum, path, output_dir) __use_cached_datasheet(partnum, path, output_dir, dstype)
# If search fails, and we don't already have the datasheet, guess datasheet URL and skip the hires image download # If search fails, and we don't already have the datasheet, guess datasheet URL and skip the hires image download
elif _try_download_datasheet(partnum, output_dir) is not False: elif _try_download_datasheet(partnum, output_dir) is not False:
__downloaded_datasheet(partnum, path, output_dir) __downloaded_datasheet(partnum, path, output_dir, dstype)
# Failed to download with search or guess :( # Failed to download with search or guess :(
else: else:
@ -213,7 +254,7 @@ def get_multi(partnums):
# We already have a hi-res image and the datasheet - perfect! # We already have a hi-res image and the datasheet - perfect!
else: else:
fprint("Using cached hi-res part image for " + partnum) fprint("Using cached hi-res part image for " + partnum)
__use_cached_datasheet(partnum, path, output_dir) __use_cached_datasheet(partnum, path, output_dir, dstype)
if len(failed) > 0: if len(failed) > 0:
fprint("Failed to download:") fprint("Failed to download:")
@ -227,21 +268,22 @@ def get_multi(partnums):
if __name__ == "__main__": if __name__ == "__main__":
partnums = ["10GXS12", "RST 5L-RKT 5L-949", partnums = ["BL7958A", "BL10GXS12", "BLRST 5L-RKT 5L-949",
"10GXS13", "BL10GXS13",
"10GXW12", "BL10GXW12",
"10GXW13", "BL10GXW13",
"2412", "BL2412",
"2413", "BL2413",
"OSP6AU", "BLOSP6AU",
"FI4D024P9", "BLFI4D024P9",
"FISD012R9", "BLFISD012R9",
"FDSD012A9", "BLFDSD012A9",
"FSSL024NG", "BLFSSL024NG",
"FISX006W0", "BLFISX006W0",
"FISX00103", "BLFISX00103",
"C6D1100007" "BLC6D1100007"
] ]
get_multi(partnums) get_multi(partnums)
#query_search("3248", "Alphawire")

359
inv_kin_testing.ipynb Normal file

File diff suppressed because one or more lines are too long

View File

@ -178,9 +178,9 @@ def init():
sendall(data) sendall(data)
#time.sleep(50000) #time.sleep(50000)
fprint("Running start-up test sequence...") fprint("Running start-up test sequence...")
for y in range(1): for y in range(100):
for x in range(len(leds)): for x in range(len(leds)):
setpixel(5,5,5,x) setpixel(0,0,150,x)
sendall(data) sendall(data)
#time.sleep(2) #time.sleep(2)
#alloffsmooth() #alloffsmooth()
@ -290,7 +290,7 @@ def close():
time.sleep(0.5) time.sleep(0.5)
sender.stop() sender.stop()
def mapimage(image, fps=60): def mapimage(image, fps=90):
global start global start
while uptime() - start < 1/fps: while uptime() - start < 1/fps:
time.sleep(0.00001) time.sleep(0.00001)

BIN
map.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 381 KiB

After

Width:  |  Height:  |  Size: 381 KiB

View File

@ -9,8 +9,10 @@ from PIL import Image
import io import io
import json import json
from util import fprint from util import fprint
import uuid
from util import run_cmd
def parse(filename, output_dir): def parse(filename, output_dir, partnum, dstype):
# Extract table data # Extract table data
@ -22,6 +24,7 @@ def parse(filename, output_dir):
page = reader.pages[0] page = reader.pages[0]
table_list = {} table_list = {}
for table in tables: for table in tables:
table.df.infer_objects(copy=False)
table.df.replace('', np.nan, inplace=True) table.df.replace('', np.nan, inplace=True)
table.df.dropna(inplace=True, how="all") table.df.dropna(inplace=True, how="all")
table.df.dropna(inplace=True, axis="columns", how="all") table.df.dropna(inplace=True, axis="columns", how="all")
@ -137,44 +140,104 @@ def parse(filename, output_dir):
# multi-page table check # multi-page table check
if table_name.isdigit() and len(tables) > 1: if dstype == "Belden":
fprint(table_name) if table_name.isdigit() and len(tables) > 1:
fprint(previous_table) fprint(table_name)
fprint(previous_table)
main_key = previous_table
cont_key = table_name main_key = previous_table
fprint(tables) cont_key = table_name
if vertical == False: fprint(tables)
main_keys = list(tables[main_key].keys()) if vertical == False:
for i, (cont_key, cont_values) in enumerate(tables[cont_key].items()): main_keys = list(tables[main_key].keys())
if i < len(main_keys): for i, (cont_key, cont_values) in enumerate(tables[cont_key].items()):
fprint(tables[main_key][main_keys[i]]) if i < len(main_keys):
tables[main_key][main_keys[i]] = (tables[main_key][main_keys[i]] + (cont_key,) + cont_values) fprint(tables[main_key][main_keys[i]])
tables[main_key][main_keys[i]] = (tables[main_key][main_keys[i]] + (cont_key,) + cont_values)
del tables[table_name]
del tables[table_name]
else:
for key in tables[cont_key].keys(): else:
tables[main_key][key] = tables[cont_key][key] for key in tables[cont_key].keys():
del tables[table_name] tables[main_key][key] = tables[cont_key][key]
del tables[table_name]
previous_table = table_name previous_table = table_name
# remove multi-line values that occasionally squeak through
def replace_newlines_in_dict(d):
for key, value in d.items():
if isinstance(value, str):
# Replace \n with " " if the value is a string
d[key] = value.replace('\n', ' ')
elif isinstance(value, dict):
# Recursively call the function if the value is another dictionary
replace_newlines_in_dict(value)
return d
tables = replace_newlines_in_dict(tables)
fprint(tables) # summary
with open(output_dir + "/tables.json", 'w') as json_file:
json.dump(tables, json_file) output_table = dict()
output_table["partnum"] = partnum
id = str(uuid.uuid4())
output_table["id"] = id
#output_table["position"] = id
#output_table["brand"] = brand
output_table["fullspecs"] = tables
output_table["searchspecs"] = {"partnum": partnum, **flatten(tables)}
output_table["searchspecs"]["id"] = id
print(output_table)
run_cmd("rm " + output_dir + "/*.json") # not reliable!
with open(output_dir + "/" + output_table["searchspecs"]["id"] + ".json", 'w') as json_file:
json.dump(output_table["searchspecs"], json_file)
return output_table
def flatten(tables):
def convert_to_number(s):
try:
# First, try converting to an integer.
return int(s)
except ValueError:
# If that fails, try converting to a float.
try:
return float(s)
except ValueError:
# If it fails again, return the original string.
return s
out = dict()
print("{")
for table in tables.keys():
for key in tables[table].keys():
if len(key) < 64:
keyname = key
else:
keyname = key[0:64]
return tables fullkeyname = (table + ": " + keyname).replace(".","")
if type(tables[table][key]) is not tuple:
out[fullkeyname] = convert_to_number(tables[table][key])
print("\"" + keyname + "\":", "\"" + str(out[fullkeyname]) + "\",")
elif len(tables[table][key]) == 1:
out[fullkeyname] = convert_to_number(tables[table][key][0])
print("\"" + keyname + "\":", "\"" + str(out[fullkeyname]) + "\",")
print("}")
return out
if __name__ == "__main__": if __name__ == "__main__":
parse("test2.pdf", "10GXS13") parse("test2.pdf", "cables/10GXS13", "10GXS13")

View File

@ -5,13 +5,15 @@ pypdf2==2.12.1
alive-progress alive-progress
requests requests
git+https://github.com/Byeongdulee/python-urx.git git+https://github.com/Byeongdulee/python-urx.git
psycopg2 psycopg2-binary
pyyaml pyyaml
Flask Flask
selenium selenium
sacn sacn
uptime uptime
websockets websockets
numpy
scipy
# Development # Development
matplotlib matplotlib

View File

@ -1,6 +1,8 @@
import urx import urx
import math3d as m3d import math3d as m3d
from scipy.optimize import fsolve
import math import math
import numpy as np
import time import time
import os import os
import logging import logging
@ -8,6 +10,9 @@ from urx.robotiq_two_finger_gripper import Robotiq_Two_Finger_Gripper
import sys import sys
from util import fprint from util import fprint
rob = None rob = None
@ -45,7 +50,7 @@ def init(ip):
time.sleep(0.2) time.sleep(0.2)
fprint("UR5 ready.") fprint("UR5 ready.")
def set_pos_abs(x, y, z, xb, yb, zb): def set_pos_abs(x, y, z, xb, yb, zb, threshold=None):
global rob global rob
new_orientation = m3d.Transform() new_orientation = m3d.Transform()
new_orientation.orient.rotate_xb(xb) # Replace rx with the desired rotation around X-axis new_orientation.orient.rotate_xb(xb) # Replace rx with the desired rotation around X-axis
@ -60,7 +65,7 @@ def set_pos_abs(x, y, z, xb, yb, zb):
new_trans.pos.y = y new_trans.pos.y = y
new_trans.pos.z = z new_trans.pos.z = z
#rob.speedj(0.2, 0.5, 99999) #rob.speedj(0.2, 0.5, 99999)
rob.set_pose(new_trans, acc=2, vel=2, command="movej") # apply the new pose rob.set_pose(new_trans, acc=2, vel=2, command="movej", threshold=threshold) # apply the new pose
def set_pos_rel_rot_abs(x, y, z, xb, yb, zb): def set_pos_rel_rot_abs(x, y, z, xb, yb, zb):
global rob global rob
@ -80,21 +85,241 @@ def set_pos_rel_rot_abs(x, y, z, xb, yb, zb):
#rob.speedj(0.2, 0.5, 99999) #rob.speedj(0.2, 0.5, 99999)
rob.set_pose(new_trans, acc=0.1, vel=0.4, command="movej") # apply the new pose rob.set_pose(new_trans, acc=0.1, vel=0.4, command="movej") # apply the new pose
def set_pos_abs_rot_rel(x, y, z, xb, yb, zb):
global rob
new_orientation = m3d.Transform()
new_orientation.orient.rotate_xb(xb) # Replace rx with the desired rotation around X-axis
new_orientation.orient.rotate_yb(yb) # Replace ry with the desired rotation around Y-axis
new_orientation.orient.rotate_zb(zb) # Replace rz with the desired rotation around Z-axis
# Get the current pose
trans = rob.getl()
# Apply the new orientation while keeping the current position
new_trans = m3d.Transform(new_orientation.orient, m3d.Vector(trans[0:3]))
new_trans.pos.x = x
new_trans.pos.y = y
new_trans.pos.z = z
#rob.speedj(0.2, 0.5, 99999)
rob.set_pose(new_trans, acc=0.1, vel=0.4, command="movej") # apply the new pose
def is_safe_move(start_pose, end_pose, r=0.25):
start_x, start_y = (start_pose[0], start_pose[1])
end_x, end_y = (end_pose[0], end_pose[1])
try:
m = (end_y-start_y)/(end_x-start_x)
b = start_y - m*start_x
# print('m = y/x =', m)
# print('b =', b)
except:
m = (end_x-start_x)/(end_y-start_y)
b = start_x - m*start_y
# print('m = x/y =', m)
# print('b =', b)
return r**2 - b**2 + m**2 * r**2 < 0
def cartesian_to_polar(x, y):
r = np.sqrt(x**2 + y**2)
theta = np.arctan2(y, x)
return r, theta
def polar_to_cartesian(r, theta):
x = r * np.cos(theta)
y = r * np.sin(theta)
return x, y
def move_to_polar(start_pos, end_pos):
global rob
# Convert to polar coordinates
start_r, start_theta = cartesian_to_polar(start_pos[0], start_pos[1])
end_r, end_theta = cartesian_to_polar(end_pos[0], end_pos[1])
# Interpolate for xy (spiral arc)
n_points = 30
r_intermediate = np.linspace(start_r, end_r, n_points)
theta_intermediate = np.linspace(start_theta, end_theta, n_points)
# Interpolate for z (height)
start_z = start_pos[2]
end_z = end_pos[2]
z_intermediate = np.linspace(start_z, end_z, n_points)
# Interpolate for rz (keep tool rotation fixed relative to robot)
curr_rot = rob.getl()
theta_delta = theta_intermediate[1]-theta_intermediate[0]
rx_intermediate = [curr_rot[5] + theta_delta*i for i in range(n_points)]
# curr_rot = rob.getj()
# start_rz = curr_rot[5]
# rot = end_theta - start_theta
# end_base_joint = curr_rot[0]-start_theta + rot
# end_rz = curr_rot[0] + rot
# # rob.movel([*polar_to_cartesian(end_r, end_theta), *rob.getl()[2:]], acc=2, vel=2)
# print('start_theta = ', math.degrees(start_theta))
# print('end_theta = ', math.degrees(curr_rot[0]-start_theta+rot))
# print('start_rz =', math.degrees(start_rz))
# print('rot =', math.degrees(rot))
# print('end_rz =', math.degrees(end_rz))
# rz_intermediate = np.linspace(start_rz, end_rz, n_points)
# Convert back to cartesian coordinates
curr_pos = rob.getl()
intermediate_points = [[*polar_to_cartesian(r, theta), z, *curr_pos[3:]]
for r, theta, z, rx in zip(r_intermediate,
theta_intermediate,
z_intermediate,
rx_intermediate)]
# Move robot
rob.movels(intermediate_points, acc=2, vel=2, radius=0.1)
return rx_intermediate
def move_to_home():
global rob
# Home position in degrees
home_pos = [0.10421807948612624,
-2.206111555015423,
1.710679229503537,
-1.075834511928354,
-1.569301366430687,
1.675098295930943]
# Move robot
rob.movej(home_pos, acc=2, vel=2)
def normalize_degree(theta):
# Normalizes degree theta from -1.5pi to 1.5pi
multiplier = 1
normalized_theta = theta % (math.pi * multiplier)
# Maintain the negative sign if the original angle is negative
if theta < 0:
normalized_theta -= math.pi * multiplier
# Return angle
return normalized_theta
def get_joints_from_xyz_rel(x, y, z, initial_guess = (math.pi/2, math.pi/2, 0), limbs=(.422864, .359041, .092124)):
# Get polar coordinates of x,y pair
r, theta = cartesian_to_polar(x, y)
# Get length of each limb
l1, l2, l3 = limbs
# Formulas to find out joint positions for (r, z)
def inv_kin_r_z(p):
a, b, c = p
return (l1*math.cos(a) + l2*math.cos(a-b) + l3*math.cos(a-b-c) - r, # r
l1*math.sin(a) + l2*math.sin(a-b) - l3*math.sin(a-b-c) - z, # z
a-b-c) # wrist angle
# Normalize angles
base, shoulder, elbow, wrist = [normalize_degree(deg) for deg in [theta, *fsolve(inv_kin_r_z, initial_guess)]]
# Return result
return base, shoulder, elbow, wrist
def get_joints_from_xyz_abs(x, y, z):
joints = get_joints_from_xyz_rel(x, y, z)
# Joint offsets
# Base, Shoulder, Elbow, Wrist
inverse = [1, -1, 1, 1]
offsets = [0, 0, 0, -math.pi/2]
# Return adjusted joint positions
return [o+j*i for j, o, i in zip(joints, offsets, inverse)]
if __name__ == "__main__": if __name__ == "__main__":
#rob.movej((0, 0, 0, 0, 0, 0), 0.1, 0.2) #rob.movej((0, 0, 0, 0, 0, 0), 0.1, 0.2)
#rob.movel((x, y, z, rx, ry, rz), a, v) #rob.movel((x, y, z, rx, ry, rz), a, v)
init("192.168.1.145") init("192.168.1.145")
fprint("Current tool pose is: ", rob.getl()) print("Current tool pose is: ", rob.getl())
#set_pos_rel_rot_abs(0, 0, -0.2, math.pi, 0, -math.pi) move_to_home()
set_pos_abs(0.3, -0.2, 0.5, math.pi, 0, -math.pi)
set_pos_abs(0, 0.2, 0.6, math.pi, 0, -math.pi) home_pose = [-0.4999999077032916,
set_pos_abs(-0.5, -0.2, 0.4, math.pi, 0, -math.pi) -0.2000072960336574,
#set_pos_rel_rot_abs(0, 0, 0, math.pi, 0, -math.pi) 0.40002172976662786,
fprint("Current tool pose is: ", rob.getl()) 0,
-3.14152741295329,
0]
# time.sleep(.5)
p1 = [0,
0.6,
.4,
0.2226,
3.1126,
0.0510]
p2 = [0.171,
-0.115,
0.2,
0.2226,
3.1126,
0.0510]
curr_pos = rob.getl()
# up/down,
# tool rotation
# tool angle (shouldn't need)
# rob.set_pos(p1[0:3], acc=0.5, vel=0.5)
# set_pos_abs(*home_pose)
angles = get_joints_from_xyz_abs(0.3, 0.3, 0.3)
rob.movej([*angles, *rob.getj()[4:]], acc=1, vel=1)
angles = get_joints_from_xyz_abs(-0.3, -0.3, 0.7)
rob.movej([*angles, *rob.getj()[4:]], acc=1, vel=1)
angles = get_joints_from_xyz_abs(-0.3, 0.4, 0.2)
rob.movej([*angles, *rob.getj()[4:]], acc=1, vel=1)
# set_pos_abs(*p1)
# move = move_to_polar(p1, p2)
# for p in move:
# print(math.degrees(p))
# print("Safe? :", is_safe_move(p1, p2))
# #set_pos_rel_rot_abs(0, 0, -0.2, math.pi, 0, -math.pi)
# set_pos_abs(0.3, -0.2, 0.5, math.pi, 0, -math.pi)
# set_pos_abs(0, 0.2, 0.6, math.pi, 0, -math.pi)
# set_pos_abs(-0.5, -0.2, 0.4, math.pi, 0, -math.pi)
# #set_pos_rel_rot_abs(0, 0, 0, math.pi, 0, -math.pi)
# print("Current tool pose is: ", rob.getl())
# print("getj(): ", rob.getj())
# move_to_home()
rob.stop() rob.stop()
os.kill(os.getpid(), 9) # dirty kill of self os.kill(os.getpid(), 9) # dirty kill of self
sys.exit(0) sys.exit(0)

View File

@ -123,7 +123,7 @@ class Logger(object):
self.terminal = sys.stdout self.terminal = sys.stdout
def write(self, message): def write(self, message):
self.log.write(message) #self.log.write(message)
#close(filename) #close(filename)
#self.log = open(filename, "a") #self.log = open(filename, "a")
try: try: