Compare commits
24 Commits
dthomas-db
...
dd2559130d
Author | SHA1 | Date | |
---|---|---|---|
dd2559130d | |||
1fa7654da5 | |||
051cc1d003 | |||
e1af00e1db | |||
af6ffe451d | |||
50bf835d13 | |||
fe5de4e54c | |||
523915feb0 | |||
b5b2a936c1 | |||
afd144bd32 | |||
eb221a5206 | |||
db7c8c4577 | |||
21b1bf7992 | |||
d376dba67c | |||
95631dbdbe | |||
9aef296763 | |||
2b287492de | |||
d2a4d93590 | |||
58605dbe85 | |||
7bf3276ce9 | |||
818688452b | |||
01526524d4 | |||
33671683ea | |||
fad885c610 |
11
Dockerfile
Normal file
11
Dockerfile
Normal 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
|
@ -32,13 +32,13 @@ led:
|
||||
ledstart: 288
|
||||
ledend: 431
|
||||
mode: rgb
|
||||
- universe: 1
|
||||
ip: 192.168.68.130
|
||||
- universe: 4
|
||||
ip: 192.168.5.40
|
||||
ledstart: 432
|
||||
ledend: 575
|
||||
mode: rgb
|
||||
- universe: 4
|
||||
ip: 192.168.68.131
|
||||
- universe: 1
|
||||
ip: 192.168.5.4
|
||||
ledstart: 576
|
||||
ledend: 719
|
||||
mode: rgb
|
||||
|
110
get_specs.py
110
get_specs.py
@ -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()))
|
||||
with requests.get(token_url) as r:
|
||||
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
|
||||
# Despite the fact that I wrote it
|
||||
# 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]
|
||||
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)
|
||||
dsidx = result["Html"].index("<a href=\"/disteAPI/") + 9
|
||||
dsidx2 = result["Html"].index(partnum, dsidx) + len(partnum)
|
||||
output["datasheet"] = "https://www.alphawire.com" + result["Html"][dsidx:dsidx2]
|
||||
#"test".index()
|
||||
print(output)
|
||||
return output
|
||||
|
||||
|
||||
except:
|
||||
return False
|
||||
return False
|
||||
else:
|
||||
data_out = json.loads(result.stdout)
|
||||
return data_out
|
||||
|
||||
|
||||
def touch(path):
|
||||
with open(path, 'a'):
|
||||
@ -126,7 +161,7 @@ def get_multi(partnums):
|
||||
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
|
||||
|
||||
#fprint(url)
|
||||
@ -151,25 +186,31 @@ def get_multi(partnums):
|
||||
os.remove(partnum + "/datasheet.pdf")
|
||||
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)
|
||||
bar.text = "Using cached datasheet for " + partnum
|
||||
bar(skipped=True)
|
||||
fprint("Parsing Datasheet contents of " + partnum)
|
||||
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)
|
||||
|
||||
def __downloaded_datasheet(partnum, path, output_dir):
|
||||
def __downloaded_datasheet(partnum, path, output_dir, dstype):
|
||||
fprint("Downloaded " + path)
|
||||
bar.text = "Downloaded " + path
|
||||
bar(skipped=False)
|
||||
fprint("Parsing Datasheet contents of " + partnum)
|
||||
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)
|
||||
|
||||
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
|
||||
path = output_dir + "/datasheet.pdf"
|
||||
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):
|
||||
# Use query
|
||||
search_result = query_search(partnum.replace(" ", ""))
|
||||
search_result = query_search(partnum.replace(" ", ""), dstype)
|
||||
# Try to use belden.com search
|
||||
if search_result is not False:
|
||||
# Download high resolution part image if available and needed
|
||||
@ -190,17 +231,17 @@ def get_multi(partnums):
|
||||
|
||||
# Download datasheet from provided URL if needed
|
||||
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:
|
||||
__downloaded_datasheet(partnum, path, output_dir)
|
||||
__downloaded_datasheet(partnum, path, output_dir, dstype)
|
||||
|
||||
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
|
||||
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 :(
|
||||
else:
|
||||
@ -213,7 +254,7 @@ def get_multi(partnums):
|
||||
# We already have a hi-res image and the datasheet - perfect!
|
||||
else:
|
||||
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:
|
||||
fprint("Failed to download:")
|
||||
@ -227,21 +268,22 @@ def get_multi(partnums):
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
partnums = ["10GXS12", "RST 5L-RKT 5L-949",
|
||||
"10GXS13",
|
||||
"10GXW12",
|
||||
"10GXW13",
|
||||
"2412",
|
||||
"2413",
|
||||
"OSP6AU",
|
||||
"FI4D024P9",
|
||||
"FISD012R9",
|
||||
"FDSD012A9",
|
||||
"FSSL024NG",
|
||||
"FISX006W0",
|
||||
"FISX00103",
|
||||
"C6D1100007"
|
||||
partnums = ["BL7958A", "BL10GXS12", "BLRST 5L-RKT 5L-949",
|
||||
"BL10GXS13",
|
||||
"BL10GXW12",
|
||||
"BL10GXW13",
|
||||
"BL2412",
|
||||
"BL2413",
|
||||
"BLOSP6AU",
|
||||
"BLFI4D024P9",
|
||||
"BLFISD012R9",
|
||||
"BLFDSD012A9",
|
||||
"BLFSSL024NG",
|
||||
"BLFISX006W0",
|
||||
"BLFISX00103",
|
||||
"BLC6D1100007"
|
||||
]
|
||||
get_multi(partnums)
|
||||
#query_search("3248", "Alphawire")
|
||||
|
||||
|
||||
|
326
inv_kin_testing.ipynb
Normal file
326
inv_kin_testing.ipynb
Normal file
File diff suppressed because one or more lines are too long
@ -178,9 +178,9 @@ def init():
|
||||
sendall(data)
|
||||
#time.sleep(50000)
|
||||
fprint("Running start-up test sequence...")
|
||||
for y in range(1):
|
||||
for y in range(100):
|
||||
for x in range(len(leds)):
|
||||
setpixel(5,5,5,x)
|
||||
setpixel(0,0,150,x)
|
||||
sendall(data)
|
||||
#time.sleep(2)
|
||||
#alloffsmooth()
|
||||
@ -290,7 +290,7 @@ def close():
|
||||
time.sleep(0.5)
|
||||
sender.stop()
|
||||
|
||||
def mapimage(image, fps=60):
|
||||
def mapimage(image, fps=90):
|
||||
global start
|
||||
while uptime() - start < 1/fps:
|
||||
time.sleep(0.00001)
|
||||
|
BIN
map.png
BIN
map.png
Binary file not shown.
Before Width: | Height: | Size: 381 KiB After Width: | Height: | Size: 381 KiB |
@ -9,8 +9,10 @@ from PIL import Image
|
||||
import io
|
||||
import json
|
||||
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
|
||||
|
||||
@ -22,6 +24,7 @@ def parse(filename, output_dir):
|
||||
page = reader.pages[0]
|
||||
table_list = {}
|
||||
for table in tables:
|
||||
table.df.infer_objects(copy=False)
|
||||
table.df.replace('', np.nan, inplace=True)
|
||||
table.df.dropna(inplace=True, how="all")
|
||||
table.df.dropna(inplace=True, axis="columns", how="all")
|
||||
@ -137,44 +140,104 @@ def parse(filename, output_dir):
|
||||
|
||||
|
||||
# multi-page table check
|
||||
if table_name.isdigit() and len(tables) > 1:
|
||||
fprint(table_name)
|
||||
fprint(previous_table)
|
||||
|
||||
|
||||
|
||||
|
||||
main_key = previous_table
|
||||
cont_key = table_name
|
||||
fprint(tables)
|
||||
if vertical == False:
|
||||
main_keys = list(tables[main_key].keys())
|
||||
for i, (cont_key, cont_values) in enumerate(tables[cont_key].items()):
|
||||
if i < len(main_keys):
|
||||
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]
|
||||
|
||||
else:
|
||||
for key in tables[cont_key].keys():
|
||||
tables[main_key][key] = tables[cont_key][key]
|
||||
del tables[table_name]
|
||||
if dstype == "Belden":
|
||||
if table_name.isdigit() and len(tables) > 1:
|
||||
fprint(table_name)
|
||||
fprint(previous_table)
|
||||
|
||||
|
||||
|
||||
|
||||
main_key = previous_table
|
||||
cont_key = table_name
|
||||
fprint(tables)
|
||||
if vertical == False:
|
||||
main_keys = list(tables[main_key].keys())
|
||||
for i, (cont_key, cont_values) in enumerate(tables[cont_key].items()):
|
||||
if i < len(main_keys):
|
||||
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]
|
||||
|
||||
else:
|
||||
for key in tables[cont_key].keys():
|
||||
tables[main_key][key] = tables[cont_key][key]
|
||||
del tables[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)
|
||||
with open(output_dir + "/tables.json", 'w') as json_file:
|
||||
json.dump(tables, json_file)
|
||||
# summary
|
||||
|
||||
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__":
|
||||
parse("test2.pdf", "10GXS13")
|
||||
parse("test2.pdf", "cables/10GXS13", "10GXS13")
|
@ -5,13 +5,15 @@ pypdf2==2.12.1
|
||||
alive-progress
|
||||
requests
|
||||
git+https://github.com/Byeongdulee/python-urx.git
|
||||
psycopg2
|
||||
psycopg2-binary
|
||||
pyyaml
|
||||
Flask
|
||||
selenium
|
||||
sacn
|
||||
uptime
|
||||
websockets
|
||||
numpy
|
||||
scipy
|
||||
|
||||
# Development
|
||||
matplotlib
|
||||
|
243
ur5_control.py
243
ur5_control.py
@ -1,6 +1,8 @@
|
||||
import urx
|
||||
import math3d as m3d
|
||||
from scipy.optimize import fsolve
|
||||
import math
|
||||
import numpy as np
|
||||
import time
|
||||
import os
|
||||
import logging
|
||||
@ -8,6 +10,9 @@ from urx.robotiq_two_finger_gripper import Robotiq_Two_Finger_Gripper
|
||||
import sys
|
||||
from util import fprint
|
||||
|
||||
|
||||
|
||||
|
||||
rob = None
|
||||
|
||||
|
||||
@ -45,7 +50,7 @@ def init(ip):
|
||||
time.sleep(0.2)
|
||||
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
|
||||
new_orientation = m3d.Transform()
|
||||
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.z = z
|
||||
#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):
|
||||
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.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__":
|
||||
|
||||
#rob.movej((0, 0, 0, 0, 0, 0), 0.1, 0.2)
|
||||
#rob.movel((x, y, z, rx, ry, rz), a, v)
|
||||
init("192.168.1.145")
|
||||
fprint("Current tool pose is: ", rob.getl())
|
||||
#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)
|
||||
fprint("Current tool pose is: ", rob.getl())
|
||||
print("Current tool pose is: ", rob.getl())
|
||||
move_to_home()
|
||||
|
||||
home_pose = [-0.4999999077032916,
|
||||
-0.2000072960336574,
|
||||
0.40002172976662786,
|
||||
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()
|
||||
os.kill(os.getpid(), 9) # dirty kill of self
|
||||
sys.exit(0)
|
||||
|
Reference in New Issue
Block a user