diff --git a/.gitignore b/.gitignore index 40318df..f6c6e74 100644 --- a/.gitignore +++ b/.gitignore @@ -15,7 +15,7 @@ output.mp4 # log files output.log # images -*.png +map*.png # Built app build # Generated label images diff --git a/GothamCond-Medium.otf b/GothamCond-Medium.otf new file mode 100644 index 0000000..cfe2b87 Binary files /dev/null and b/GothamCond-Medium.otf differ diff --git a/belden-logo-superhires.png b/belden-logo-superhires.png new file mode 100644 index 0000000..68d71c4 Binary files /dev/null and b/belden-logo-superhires.png differ diff --git a/belden-logo.svg b/belden-logo.svg new file mode 100644 index 0000000..0e7e668 --- /dev/null +++ b/belden-logo.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/get_specs.py b/get_specs.py index b6c4067..e31cb85 100755 --- a/get_specs.py +++ b/get_specs.py @@ -70,6 +70,8 @@ def query_search(partnum, source): if idx < 0: fprint("Could not find part in API: " + partnum) return False + + name = a["results"][idx]["title"] #fprint("Search result found: result " + str(idx) + ", for ID " + name) #urlname = a["results"][0]["raw"]["catalogitemurlname"] img = a["results"][idx]["raw"]["catalogitemimageurl"] @@ -279,6 +281,7 @@ def get_multi(partnums, delay=0.25, dir="cables/", cache=True): return out def run_search(partnum): + partnum = partnum.replace("%20", " ") # undo URL encoding oldpartnum = partnum if dstype == "Alphawire": # For alphawire, sanitize the part number for only the final result check, because their API is very wierd @@ -405,6 +408,7 @@ if __name__ == "__main__": # ] partnums = [ # Actual cables in Jukebox + "AW86104CY", "AW3050", "AW6714", @@ -437,7 +441,7 @@ if __name__ == "__main__": # Some ones I picked, including some invalid ones "BL10GXS12", - "BLRST 5L-RKT 5L-949", + "BLRST%205L-RKT%205L-949", "BL10GXS13", "BL10GXW12", "BL10GXW13", @@ -448,13 +452,18 @@ if __name__ == "__main__": "BLFISD012R9", "BLFDSD012A9", "BLFSSL024NG", - "BLFISX006W0", - "BLFISX00103", - "BLC6D1100007" + "BLFISX006W0", # datasheet only + "BLFISX00103", # invalid + "BLC6D1100007" # invalid ] - print(query_search("74002", "Belden")) - #get_multi(partnums, 0.25) + #print(query_search("TT-SLG-024-HTNN", "Belden")) + from label_generator import gen_label + gen_label("BLTF-SD9-006-RI5") + gen_label("BLRA500P") + gen_label("AWFIT-221-1_4") + gen_label("BLRST 5L-RKT 5L-949") + get_multi(partnums, 0.25) #query_search("10GXS13", "Belden") diff --git a/index.html b/index.html deleted file mode 100644 index cb0c070..0000000 --- a/index.html +++ /dev/null @@ -1 +0,0 @@ - RGB Controller Configuration

RGB Controller Configuration


Set IP address

Needs reboot to apply
Set to 0.0.0.0 for DHCP
. . .

Set Hostname

Needs reboot to apply
Max 64 characters

DMX512 Start Universe

Applies immediately
Between (inclusive) 1-65000


\ No newline at end of file diff --git a/label_generator.py b/label_generator.py index f0fbaa9..9551999 100755 --- a/label_generator.py +++ b/label_generator.py @@ -61,9 +61,15 @@ def input_cable(): imgstr = "BL" elif output[1] == "Alphawire": imgstr = "AW" - img = generate_code(imgstr + output[0]) - os.makedirs("labels", exist_ok=True) - img.save("labels/" + imgstr + output[0] + ".png") + gen_label(imgstr + output[0]) + #img = generate_code(imgstr + output[0]) + #os.makedirs("labels", exist_ok=True) + #img.save("labels/" + imgstr + output[0] + ".png") + +def gen_label(partnum, path="labels"): + img = generate_code(partnum) + os.makedirs(path, exist_ok=True) + img.save(path + "/" + partnum + ".png") def delete_folder(path): # Check if the path is a directory diff --git a/label_image.py b/label_image.py index 17de9ba..56429bc 100755 --- a/label_image.py +++ b/label_image.py @@ -3,8 +3,13 @@ from util import fprint from PIL import Image from PIL import ImageDraw +from PIL import ImageFont #import cv2 import numpy as np +from util import find_data_file +import segno +import io +#import cairosvg #import math @@ -134,7 +139,8 @@ for charset in (CODE128A, CODE128B): def generate_code(data, show=False, check=False): - img = code128_image(data) + #img = code128_image(data) + img = qr_image(data) if show: img.show() #img.show() @@ -198,6 +204,7 @@ def code128_format(data): return codes def code128_image(data, height=100, thickness=3, quiet_zone=False): + partnum = data if not data[-1] == CODE128B['Stop']: data = code128_format(data) @@ -227,12 +234,86 @@ def code128_image(data, height=100, thickness=3, quiet_zone=False): #draw.arc(((width - width/5, width - width/5), (width*9 + width/5, width*9 + width/5)),0,360,fill='blue', width = int(width/8)) draw.arc(((width+int(width / 1.4), width+int(width / 1.4)), (width*9-int(width / 1.4), width*9-int(width / 1.4))),0,360,fill='blue', width = int(width/8)) + font_path = find_data_file("OCRAEXT.TTF") + font_size = width/2 + font = ImageFont.truetype(font_path, font_size) + text_width = font.getlength(partnum) + while text_width > width*4: + font_size -= 1 + font = ImageFont.truetype(font_path, font_size) + text_width = font.getlength(partnum) + + txtx = (int(width * 10) - text_width) / 2 + txty = (int(width * 10)) / 2 + width / 2 + + draw.text((txtx,txty),partnum, "black", font) + return img + +def qr_image(data, width=600): + partnum = data + + + + # Monochrome Image + img = Image.new('RGB', (int(width * 10), int(width * 10)), 'white') + draw = ImageDraw.Draw(img) + + + + #svg_path = find_data_file("belden-logo.svg") + #with open(svg_path, 'rb') as svg_file: + # png_image = cairosvg.svg2png(file_obj=svg_file,dpi=width*30, scale=30, background_color="white") + #with open("output.png", 'wb') as file: + # file.write(png_image) + + png_image_io = "belden-logo-superhires.png" + png_image_pillow = Image.open(png_image_io) + png_width, png_height = png_image_pillow.size + png_image_pillow = png_image_pillow.resize((int(width*5.2), int(width*5.2/png_width*png_height))) + png_width, png_height = png_image_pillow.size + # paste belden logo first because it has a big border that would cover stuff up + img.paste(png_image_pillow, (int(width*5-png_width/2), int(width*4.25 - png_height/2))) + + # draw circle border + #draw.arc(((width - width/5, width - width/5), (width*9 + width/5, width*9 + width/5)),0,360,fill='blue', width = int(width/8)) + draw.arc(((width+int(width / 1.4), width+int(width / 1.4)), (width*9-int(width / 1.4), width*9-int(width / 1.4))),0,360,fill=(0, 73,144), width = int(width/8)) + + font_path = find_data_file("GothamCond-Medium.otf") + font_size = width/2 + font = ImageFont.truetype(font_path, font_size) + text_width = font.getlength(partnum[2:]) + # shrink font dynamically if it's too long of a name + while text_width > width*4: + font_size -= 1 + font = ImageFont.truetype(font_path, font_size) + text_width = font.getlength(partnum[2:]) + + txtx = (int(width * 10) - text_width) / 2 + txty = (int(width * 10)) / 2 + # draw part number text + draw.text((txtx,txty),partnum[2:], "black", font) + + # Draw QR code + partnum = partnum.replace(" ", "%20") + qrcode = segno.make('HTTPS://BLDN.APP/' + partnum,micro=False,boost_error=False,error="L",mask=3) + out = io.BytesIO() + qrx, _ = qrcode.symbol_size(1,0) + qrcode.save(out, scale=width*2/qrx, kind="PNG", border=0) + qrimg = Image.open(out) + img.paste(qrimg, box=(int(width*4),int(width*5.75))) + + return img if __name__ == "__main__": #print(generate_code("BL10GXS13")) #print(generate_code("BL10GXgd35j35S13")) #print(generate_code("BL10GX54hS13")) - print(generate_code("BL10Gj34qXS13", False, False)) + #print(generate_code("BL10Gj34qXS13", False, False)) #print(generate_code("BL104w5545dp7bfwp43643534/4563G-XS13")) - #adjust_image(cv2.imread('test_skew.jpg')) \ No newline at end of file + #adjust_image(cv2.imread('test_skew.jpg')) + path = "labels" + img = generate_code("BL10GXS13") + import os + os.makedirs(path, exist_ok=True) + img.save(path + "/" + "BL10GXS13" + ".png") \ No newline at end of file diff --git a/led_control.py b/led_control.py index fe38f11..641d64a 100755 --- a/led_control.py +++ b/led_control.py @@ -14,665 +14,653 @@ import cv2 import numpy as np from uptime import uptime -sender = None -debug = True -config = None -leds = None -leds_size = None -leds_normalized = None -controllers = None -data = None -exactdata = None -rings = None -ringstatus = None -mode = "Startup" -firstrun = True -changecount = 0 -animation_time = 0 -start = uptime() -def ping(host): - #Returns True if host (str) responds to a ping request. - # Option for the number of packets as a function of - if win32: - param1 = '-n' - param2 = '-w' - param3 = '250' - else: - param1 = '-c' - param2 = '-W' - param3 = '0.25' - - # Building the command. Ex: "ping -c 1 google.com" - command = ['ping', param1, '1', param2, param3, host] - - return subprocess.call(command, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT) == 0 - -def map(): - global config - global leds - global leds_size - global leds_normalized - global controllers - global rings - global ringstatus - global animation_time +class LEDSystem(): + sender = None + debug = True + config = None + leds = None + leds_size = None + leds_normalized = None + controllers = None + data = None + exactdata = None + rings = None + ringstatus = None + mode = "Startup" + firstrun = True + changecount = 0 + animation_time = 0 + start = uptime() + def __init__(self): + self.start = uptime() + #self.init() + #return self - with open('config.yml', 'r') as fileread: - #global config - config = yaml.safe_load(fileread) + def ping(self, host): + #Returns True if host (str) responds to a ping request. - animation_time = config["animation_time"] - leds = list() - leds_size = list() - controllers = list() - rings = list(range(len(config["position_map"]))) - ringstatus = list(range(len(config["position_map"]))) - #print(rings) - #fprint(config["led"]["map"]) - generate_map = False - map = list() - for shape in config["led"]["map"]: - if shape["type"] == "circle": - - if generate_map: - map.append((shape["pos"][1],shape["pos"][0])) - #fprint(shape["pos"]) - anglediv = 360.0 / shape["size"] - angle = 0 - radius = shape["diameter"] / 2 - lednum = shape["start"] - for item in config['position_map']: - # Check if the current item's position matches the target position - #print(item['pos'],(shape["pos"][1],shape["pos"][0])) - if tuple(item['pos']) == (shape["pos"][1],shape["pos"][0]): - rings[item["index"]] = (shape["pos"][1],shape["pos"][0],lednum,lednum+shape["size"]) # rings[index] = x, y, startpos, endpos - ringstatus[item["index"]] = [None, None] + # Option for the number of packets as a function of + if win32: + param1 = '-n' + param2 = '-w' + param3 = '250' + else: + param1 = '-c' + param2 = '-W' + param3 = '0.25' + + # Building the command. Ex: "ping -c 1 google.com" + command = ['ping', param1, '1', param2, param3, host] + + return subprocess.call(command, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT) == 0 + + def map(self): + + with open('config.yml', 'r') as fileread: + #global config + self.config = yaml.safe_load(fileread) + + self.animation_time = self.config["animation_time"] + self.leds = list() + self.leds_size = list() + self.controllers = list() + self.rings = list(range(len(self.config["position_map"]))) + self.ringstatus = list(range(len(self.config["position_map"]))) + #print(rings) + #fprint(config["led"]["map"]) + generate_map = False + map = list() + for shape in self.config["led"]["map"]: + if shape["type"] == "circle": + + if generate_map: + map.append((shape["pos"][1],shape["pos"][0])) + #fprint(shape["pos"]) + anglediv = 360.0 / shape["size"] + angle = 0 + radius = shape["diameter"] / 2 + lednum = shape["start"] + for item in self.config['position_map']: + # Check if the current item's position matches the target position + #print(item['pos'],(shape["pos"][1],shape["pos"][0])) + if tuple(item['pos']) == (shape["pos"][1],shape["pos"][0]): + self.rings[item["index"]] = (shape["pos"][1],shape["pos"][0],lednum,lednum+shape["size"]) # rings[index] = x, y, startpos, endpos + self.ringstatus[item["index"]] = [None, None] + break + if len(self.leds) < lednum + shape["size"]: + for x in range(lednum + shape["size"] - len(self.leds)): + self.leds.append(None) + self.leds_size.append(None) + while angle < 359.999: + tmpangle = angle + shape["angle"] + x = math.cos(tmpangle * (math.pi / 180.0)) * radius + shape["pos"][1] # flip by 90 degress when we changed layout + y = math.sin(tmpangle * (math.pi / 180.0)) * radius + shape["pos"][0] + self.leds[lednum] = (x,y) + lednum = lednum + 1 + angle = angle + anglediv + + elif shape["type"] == "strip": + angle = shape["angle"] + lednum = shape["start"] + length = shape["length"] + distdiv = length / shape["size"] + dist = distdiv / 2 + xmov = math.cos(angle * (math.pi / 180.0)) * distdiv + ymov = math.sin(angle * (math.pi / 180.0)) * distdiv + pos = shape["pos"] + if len(self.leds) < lednum + shape["size"]: + for x in range(lednum + shape["size"] - len(self.leds)): + self.leds.append(None) + self.leds_size.append(None) + + while dist < length: + self.leds[lednum] = (pos[0], pos[1]) + pos[0] += xmov + pos[1] += ymov + dist += distdiv + lednum = lednum + 1 + + if generate_map: + map = sorted(map, key=lambda x: (-x[1], x[0])) + print(map) + import matplotlib.pyplot as plt + plt.axis('equal') + x, y = zip(*map) + plt.scatter(x, y, s=12) + #plt.plot(x, y, marker='o') + #plt.scatter(*zip(*leds), s=3) + for i, (x_pos, y_pos) in enumerate(map): + plt.text(x_pos, y_pos, str(i), color="red", fontsize=12) + plt.savefig("map2.png", dpi=600, bbox_inches="tight") + data = {"map": [{"index": i, "pos": str(list(pos))} for i, pos in enumerate(map)]} + yaml_str = yaml.dump(data, default_flow_style=False) + print(yaml_str) + + print(self.rings) + flag = 0 + for x in self.leds: + if x is None: + flag = flag + 1 + if flag > 0: + fprint("Warning: Imperfect LED map ordering. Hiding undefined lights.") + for x in range(len(self.leds)): + if self.leds[x] is None: + self.leds[x] = (0, 0) + + + #leds = tmpleds.reverse() + #fprint(leds) + + # controller mapping + for ctrl in self.config["led"]["controllers"]: + if len(self.controllers) < ctrl["universe"]+1: + for x in range(ctrl["universe"]+1 - len(self.controllers)): + self.controllers.append(None) + + self.controllers[ctrl["universe"]] = (ctrl["ledstart"],ctrl["ledend"]+1,ctrl["ip"]) + for x in range(ctrl["ledstart"],ctrl["ledend"]+1): + self.leds_size[x] = len(ctrl["mode"]) + #fprint(controllers) + + if(self.debug): + import matplotlib.pyplot as plt + plt.axis('equal') + for ctrl in self.controllers: + plt.scatter(*zip(*self.leds[ctrl[0]:ctrl[1]]), s=2) + #plt.scatter(*zip(*leds), s=3) + plt.savefig("map.png", dpi=600, bbox_inches="tight") + + leds_adj = [(x-min([led[0] for led in self.leds]), # push to zero start + y-min([led[1] for led in self.leds]) ) + for x, y in self.leds] + + self.leds_normalized = [(x / max([led[0] for led in leds_adj]), + y / max([led[1] for led in leds_adj])) + for x, y in leds_adj] + #return leds, controllers + + def init(self): + self.map() + self.sender = sacn.sACNsender(fps=self.config["led"]["fps"], universeDiscovery=False) + self.sender.start() # start the sending thread + """for x in range(len(self.controllers)): + print("Waiting for the controller at", self.controllers[x][2], "to be online...", end="") + count = 0 + while not ping(self.controllers[x][2]): + count = count + 1 + if count >= self.config["led"]["timeout"]: + fprint(" ERROR: controller still offline after " + str(count) + " seconds, continuing...") break - if len(leds) < lednum + shape["size"]: - for x in range(lednum + shape["size"] - len(leds)): - leds.append(None) - leds_size.append(None) - while angle < 359.999: - tmpangle = angle + shape["angle"] - x = math.cos(tmpangle * (math.pi / 180.0)) * radius + shape["pos"][1] # flip by 90 degress when we changed layout - y = math.sin(tmpangle * (math.pi / 180.0)) * radius + shape["pos"][0] - leds[lednum] = (x,y) - lednum = lednum + 1 - angle = angle + anglediv - - elif shape["type"] == "strip": - angle = shape["angle"] - lednum = shape["start"] - length = shape["length"] - distdiv = length / shape["size"] - dist = distdiv / 2 - xmov = math.cos(angle * (math.pi / 180.0)) * distdiv - ymov = math.sin(angle * (math.pi / 180.0)) * distdiv - pos = shape["pos"] - if len(leds) < lednum + shape["size"]: - for x in range(lednum + shape["size"] - len(leds)): - leds.append(None) - leds_size.append(None) - - while dist < length: - leds[lednum] = (pos[0], pos[1]) - pos[0] += xmov - pos[1] += ymov - dist += distdiv - lednum = lednum + 1 + if count < self.config["led"]["timeout"]: + fprint(" done")""" + for x in range(len(self.controllers)): + print("Activating controller", x, "at", self.controllers[x][2], "with", self.controllers[x][1]-self.controllers[x][0], "LEDs.") + self.sender.activate_output(x+1) # start sending out data + self.sender[x+1].destination = self.controllers[x][2] + self.sender.manual_flush = True - if generate_map: - map = sorted(map, key=lambda x: (-x[1], x[0])) - print(map) - import matplotlib.pyplot as plt - plt.axis('equal') - x, y = zip(*map) - plt.scatter(x, y, s=12) - #plt.plot(x, y, marker='o') - #plt.scatter(*zip(*leds), s=3) - for i, (x_pos, y_pos) in enumerate(map): - plt.text(x_pos, y_pos, str(i), color="red", fontsize=12) - plt.savefig("map2.png", dpi=600, bbox_inches="tight") - data = {"map": [{"index": i, "pos": str(list(pos))} for i, pos in enumerate(map)]} - yaml_str = yaml.dump(data, default_flow_style=False) - print(yaml_str) + # initialize global pixel data list + self.data = list() + self.exactdata = list() + for x in range(len(self.leds)): + if self.leds_size[x] == 3: + self.exactdata.append(None) + self.data.append((20,20,127)) + elif self.leds_size[x] == 4: + self.exactdata.append(None) + self.data.append((50,50,255,0)) + else: + self.exactdata.append(None) + self.data.append((0,0,0)) + self.sendall(self.data) + #time.sleep(50000) + fprint("Running start-up test sequence...") + for y in range(1): + for x in range(len(self.leds)): + self.setpixel(0,60,144,x) + self.sendall(self.data) + #time.sleep(2) + self.alloffsmooth() - print(rings) - flag = 0 - for x in leds: - if x is None: - flag = flag + 1 - if flag > 0: - fprint("Warning: Imperfect LED map ordering. Hiding undefined lights.") - for x in range(len(leds)): - if leds[x] is None: - leds[x] = (0, 0) + def sendall(self, datain): + # send all LED data to all controllers + # data must have all LED data in it as [(R,G,B,)] tuples in an array, 1 tuple per pixel + self.sender.manual_flush = True + for x in range(len(self.controllers)): + self.sender[x+1].dmx_data = list(sum(datain[self.controllers[x][0]:self.controllers[x][1]] , ())) # flatten the subsection of the data array + + self.sender.flush() + time.sleep(0.002) + #sender.flush() # 100% reliable with 2 flushes, often fails with 1 + #time.sleep(0.002) + #sender.flush() + + def fastsendall(self, datain): + # send all LED data to all controllers + # data must have all LED data in it as [(R,G,B,)] tuples in an array, 1 tuple per pixel + self.sender.manual_flush = False + print(datain[self.controllers[0][0]:self.controllers[0][1]]) + for x in range(len(self.controllers)): + self.sender[x+1].dmx_data = list(sum(datain[self.controllers[x][0]:self.controllers[x][1]] , ())) # flatten the subsection of the data array + + self.sender.flush() + + def senduniverse(self, datain, lednum): + # send all LED data for 1 controller/universe + # data must have all LED data in it as [(R,G,B,)] tuples in an array, 1 tuple per pixel + for x in range(len(self.controllers)): + if lednum >= self.controllers[x][0] and lednum < self.controllers[x][1]: + self.sender[x+1].dmx_data = list(sum(datain[self.controllers[x][0]:self.controllers[x][1]] , ())) # flatten the subsection of the data array + + self.sender.flush() + time.sleep(0.004) + #sender.flush() # 100% reliable with 2 flushes, often fails with 1 + #time.sleep(0.002) + #sender.flush() + + def alloff(self): + tmpdata = list() + for x in range(len(self.leds)): + if self.leds_size[x] == 3: + tmpdata.append((0,0,0)) + elif self.leds_size[x] == 4: + tmpdata.append((0,0,0,0)) + else: + tmpdata.append((0,0,0)) + self.sendall(tmpdata) + #sendall(tmpdata) + #sendall(tmpdata) #definitely make sure it's off + return self + + def allon(self): + self.sendall(self.data) + return self + + def alloffsmooth(self): + tmpdata = self.data + for x in range(256): + for x in range(len(self.data)): + self.setpixel(tmpdata[x][0]-1,tmpdata[x][1]-1,tmpdata[x][2]-1, x) + self.sendall(tmpdata) + + self.alloff() + return self + + def setpixelnow(self, r, g, b, num): + # slight optimization: send only changed universe + # unfortunately no way to manual flush data packets to only 1 controller with this sACN library + self.setpixel(r,g,b,num) + self.senduniverse(self.data, num) + return self + + def setmode(self, stmode, r=0,g=0,b=0): + if stmode is not None: + if self.mode != stmode: + self.firstrun = True + + self.mode = stmode + return self - #leds = tmpleds.reverse() - #fprint(leds) + def setring(self, r,g,b,idx): - # controller mapping - for ctrl in config["led"]["controllers"]: - if len(controllers) < ctrl["universe"]+1: - for x in range(ctrl["universe"]+1 - len(controllers)): - controllers.append(None) + ring = self.rings[idx] + for pixel in range(ring[2],ring[3]): + self.setpixel(r,g,b,pixel) + #global data + #senduniverse(data, ring[2]) + return self - controllers[ctrl["universe"]] = (ctrl["ledstart"],ctrl["ledend"]+1,ctrl["ip"]) - for x in range(ctrl["ledstart"],ctrl["ledend"]+1): - leds_size[x] = len(ctrl["mode"]) - #fprint(controllers) - - if(debug): - import matplotlib.pyplot as plt - plt.axis('equal') - for ctrl in controllers: - plt.scatter(*zip(*leds[ctrl[0]:ctrl[1]]), s=2) - #plt.scatter(*zip(*leds), s=3) - plt.savefig("map.png", dpi=600, bbox_inches="tight") + def runmodes(self, ring = -1, speed = 1): + fprint("Mode: " + str(self.mode)) + if self.mode == "Startup": + # loading animation. cable check + if self.firstrun: + self.changecount = self.animation_time * 3 + firstrun = False + for x in range(len(self.ringstatus)): + self.ringstatus[x] = [True, self.animation_time] - leds_adj = [(x-min([led[0] for led in leds]), # push to zero start - y-min([led[1] for led in leds]) ) - for x, y in leds] - - leds_normalized = [(x / max([led[0] for led in leds_adj]), - y / max([led[1] for led in leds_adj])) - for x, y in leds_adj] - #return leds, controllers + if self.changecount > 0: + fprint(self.changecount) + self.changecount = self.fadeorder(0,len(self.leds), self.changecount, 0,50,100) + else: + self.setmode("Startup2") -def init(): - map() - global sender - global config - global leds - global leds_size - global controllers - global data - global exactdata - sender = sacn.sACNsender(fps=config["led"]["fps"], universeDiscovery=False) - sender.start() # start the sending thread - """for x in range(len(controllers)): - print("Waiting for the controller at", controllers[x][2], "to be online...", end="") - count = 0 - while not ping(controllers[x][2]): - count = count + 1 - if count >= config["led"]["timeout"]: - fprint(" ERROR: controller still offline after " + str(count) + " seconds, continuing...") - break - if count < config["led"]["timeout"]: - fprint(" done")""" - for x in range(len(controllers)): - print("Activating controller", x, "at", controllers[x][2], "with", controllers[x][1]-controllers[x][0], "LEDs.") - sender.activate_output(x+1) # start sending out data - sender[x+1].destination = controllers[x][2] - sender.manual_flush = True - # initialize global pixel data list - data = list() - exactdata = list() - for x in range(len(leds)): - if leds_size[x] == 3: - exactdata.append(None) - data.append((20,20,127)) - elif leds_size[x] == 4: - exactdata.append(None) - data.append((50,50,255,0)) - else: - exactdata.append(None) - data.append((0,0,0)) - sendall(data) - #time.sleep(50000) - fprint("Running start-up test sequence...") - for y in range(1): - for x in range(len(leds)): - setpixel(0,60,144,x) - sendall(data) - #time.sleep(2) - alloffsmooth() + elif self.mode == "Startup2": + if self.firstrun: + self.firstrun = False -def sendall(datain): - # send all LED data to all controllers - # data must have all LED data in it as [(R,G,B,)] tuples in an array, 1 tuple per pixel - global controllers - global sender - sender.manual_flush = True - for x in range(len(controllers)): - sender[x+1].dmx_data = list(sum(datain[controllers[x][0]:controllers[x][1]] , ())) # flatten the subsection of the data array - - sender.flush() - time.sleep(0.002) - #sender.flush() # 100% reliable with 2 flushes, often fails with 1 - #time.sleep(0.002) - #sender.flush() + else: + for x in range(len(self.ringstatus)): + if self.ringstatus[x][0]: + self.setring(0, 50, 100, x) + else: + self.ringstatus[x][1] = self.fadeall(self.rings[x][2],self.rings[x][3], self.ringstatus[x][1], 100,0,0) # not ready -def fastsendall(datain): - # send all LED data to all controllers - # data must have all LED data in it as [(R,G,B,)] tuples in an array, 1 tuple per pixel - global controllers - global sender - sender.manual_flush = False - print(datain[controllers[0][0]:controllers[0][1]]) - for x in range(len(controllers)): - sender[x+1].dmx_data = list(sum(datain[controllers[x][0]:controllers[x][1]] , ())) # flatten the subsection of the data array - - sender.flush() + elif self.mode == "StartupCheck": + if self.firstrun: + self.firstrun = False + for x in range(len(self.ringstatus)): + self.ringstatus[x] = [False, self.animation_time] + else: + for x in range(len(self.ringstatus)): + if self.ringstatus[x][0]: + self.ringstatus[x][1] = self.fadeall(self.rings[x][2],self.rings[x][3], self.ringstatus[x][1], 0,50,100) # ready + else: + self.setring(100, 0, 0, x) -def senduniverse(datain, lednum): - # send all LED data for 1 controller/universe - # data must have all LED data in it as [(R,G,B,)] tuples in an array, 1 tuple per pixel - global controllers - global sender - for x in range(len(controllers)): - if lednum >= controllers[x][0] and lednum < controllers[x][1]: - sender[x+1].dmx_data = list(sum(datain[controllers[x][0]:controllers[x][1]] , ())) # flatten the subsection of the data array - - sender.flush() - time.sleep(0.004) - #sender.flush() # 100% reliable with 2 flushes, often fails with 1 - #time.sleep(0.002) - #sender.flush() + elif self.mode == "GrabA": + if self.firstrun: + self.firstrun = False + self.changecount = self.animation_time # 100hz + if self.changecount > 0: + self.changecount = self.fadeall(self.rings[ring][2],self.rings[ring][3], self.changecount, 100,0,0) + else: + self.setring(100,0,0,ring) + self.setmode("GrabB") + elif self.mode == "GrabB": + if self.firstrun: + self.firstrun = False + self.changecount = self.animation_time # 100hz + if self.changecount > 0: + self.changecount = self.fadeorder(self.rings[ring][2],self.rings[ring][3], self.changecount, 0,100,0) + else: + self.setring(0,100,0,ring) + self.setmode("idle") + elif self.mode == "GrabC": + if self.firstrun: + self.firstrun = False + self.changecount = self.animation_time # 100hz + if self.changecount > 0: + self.changecount = self.fadeall(self.rings[ring][2],self.rings[ring][3], self.changecount, 0,50,100) + else: + self.setring(0,50,100,ring) + self.setmode("idle") + elif self.mode == "idle": + time.sleep(0) -def alloff(): - tmpdata = list() - for x in range(len(leds)): - if leds_size[x] == 3: - tmpdata.append((0,0,0)) - elif leds_size[x] == 4: - tmpdata.append((0,0,0,0)) - else: - tmpdata.append((0,0,0)) - sendall(tmpdata) - #sendall(tmpdata) - #sendall(tmpdata) #definitely make sure it's off + self.sendall(self.data) + return self -def allon(): - global data - sendall(data) + def fadeall(self, idxa,idxb,sizerem,r,g,b): + if sizerem < 1: + return 0 + sum = 0 + for x in range(idxa,idxb): + if self.exactdata[x] is None: + self.exactdata[x] = self.data[x] + old = self.exactdata[x] + dr = (r - old[0])/sizerem + sum += abs(dr) + dr += old[0] + dg = (g - old[1])/sizerem + sum += abs(dg) + dg += old[1] + db = (b - old[2])/sizerem + db += old[2] + sum += abs(db) + self.exactdata[x] = (dr, dg, db) + #print(new) + self.setpixel(dr, dg, db, x) + if sizerem == 1: + self.exactdata[x] = None + if sum == 0 and sizerem > 2: + sizerem = 2 + return sizerem - 1 -def alloffsmooth(): - tmpdata = data - for x in range(256): - for x in range(len(data)): - setpixel(tmpdata[x][0]-1,tmpdata[x][1]-1,tmpdata[x][2]-1, x) - sendall(tmpdata) + def fadeorder(self, idxa,idxb,sizerem,r,g,b): + if sizerem < 1: + return 0 + drs = 0 + dgs = 0 + dbs = 0 + sum = 0 + for x in range(idxa,idxb): + if self.exactdata[x] is None: + self.exactdata[x] = self.data[x] + old = self.exactdata[x] + dr = (r - old[0]) + dg = (g - old[1]) + db = (b - old[2]) + drs += dr + dgs += dg + dbs += db - alloff() - -def setpixelnow(r, g, b, num): - # slight optimization: send only changed universe - # unfortunately no way to manual flush data packets to only 1 controller with this sACN library - global data - setpixel(r,g,b,num) - senduniverse(data, num) - -def setmode(stmode, r=0,g=0,b=0): - global mode - global firstrun - if stmode is not None: - if mode != stmode: - firstrun = True - - mode = stmode - - -def setring(r,g,b,idx): - - ring = rings[idx] - for pixel in range(ring[2],ring[3]): - setpixel(r,g,b,pixel) - #global data - #senduniverse(data, ring[2]) - -def runmodes(ring = -1, speed = 1): - global mode - global firstrun - global changecount - fprint("Mode: " + str(mode)) - if mode == "Startup": - # loading animation. cable check - if firstrun: - changecount = animation_time * 3 - firstrun = False - for x in range(len(ringstatus)): - ringstatus[x] = [True, animation_time] - - if changecount > 0: - fprint(changecount) - changecount = fadeorder(0,len(leds), changecount, 0,50,100) - else: - setmode("Startup2") - - - elif mode == "Startup2": - if firstrun: - firstrun = False - - else: - for x in range(len(ringstatus)): - if ringstatus[x][0]: - setring(0, 50, 100, x) + drs /= sizerem + dgs /= sizerem + dbs /= sizerem + sum += abs(drs) + abs(dgs) + abs(dbs) + print(drs,dgs,dbs) + for x in range(idxa,idxb): + old = self.exactdata[x] + new = list(old) + if drs > 0: + if old[0] + drs > r: + new[0] = r + drs -= r - old[0] else: - ringstatus[x][1] = fadeall(rings[x][2],rings[x][3], ringstatus[x][1], 100,0,0) # not ready - - elif mode == "StartupCheck": - if firstrun: - firstrun = False - for x in range(len(ringstatus)): - ringstatus[x] = [False, animation_time] - else: - for x in range(len(ringstatus)): - if ringstatus[x][0]: - ringstatus[x][1] = fadeall(rings[x][2],rings[x][3], ringstatus[x][1], 0,50,100) # ready + new[0] = old[0] + drs + drs = 0 + if dgs > 0: + if old[1] + dgs > g: + new[1] = g + dgs -= g - old[1] else: - setring(100, 0, 0, x) + new[1] = old[1] + dgs + dgs = 0 + if dbs > 0: + if old[2] + dbs > b: + new[2] = b + dbs -= b - old[2] + else: + new[2] = old[2] + dbs + dbs = 0 - elif mode == "GrabA": - if firstrun: - firstrun = False - changecount = animation_time # 100hz - if changecount > 0: - changecount = fadeall(rings[ring][2],rings[ring][3], changecount, 100,0,0) + if drs < 0: + if old[0] + drs < r: + new[0] = r + drs -= r - old[0] + else: + new[0] = old[0] + drs + drs = 0 + if dgs < 0: + if old[1] + dgs < g: + new[1] = g + dgs -= g - old[1] + else: + new[1] = old[1] + dgs + dgs = 0 + if dbs < 0: + if old[2] + dbs < b: + new[2] = b + dbs -= b - old[2] + else: + new[2] = old[2] + dbs + dbs = 0 + + if drs != 0 or dgs != 0 or dbs != 0: + self.exactdata[x] = new + self.setpixel(new[0],new[1],new[2],x) + + if sizerem == 1: + self.exactdata[x] = None + + if sum == 0 and sizerem > 2: + sizerem = 2 + return sizerem - 1 + + + def setpixel(self, r, g, b, num): + # constrain values + if r < 0: + r = 0 + elif r > 255: + r = 255 + if g < 0: + g = 0 + elif g > 255: + g = 255 + if b < 0: + b = 0 + elif b > 255: + b = 255 + + if self.leds_size[num] == 3: + self.data[num] = (int(r), int(g), int(b)) + elif self.leds_size[num] == 4: # cut out matching white and turn on white pixel instead + self.data[num] = (( int(r) - int(min(r,g,b)), int(g) - int(min(r,g,b)), int(b) - int(min(r,g,b)), int(min(r,g,b))) ) else: - setring(100,0,0,ring) - setmode("GrabB") - elif mode == "GrabB": - if firstrun: - firstrun = False - changecount = animation_time # 100hz - if changecount > 0: - changecount = fadeorder(rings[ring][2],rings[ring][3], changecount, 0,100,0) - else: - setring(0,100,0,ring) - setmode("idle") - elif mode == "GrabC": - if firstrun: - firstrun = False - changecount = animation_time # 100hz - if changecount > 0: - changecount = fadeall(rings[ring][2],rings[ring][3], changecount, 0,50,100) - else: - setring(0,50,100,ring) - setmode("idle") - elif mode == "idle": - time.sleep(0) + self.data[num] = (int(r), int(g), int(b)) + return self - sendall(data) - -def fadeall(idxa,idxb,sizerem,r,g,b): - if sizerem < 1: - return 0 - global exactdata - sum = 0 - for x in range(idxa,idxb): - if exactdata[x] is None: - exactdata[x] = data[x] - old = exactdata[x] - dr = (r - old[0])/sizerem - sum += abs(dr) - dr += old[0] - dg = (g - old[1])/sizerem - sum += abs(dg) - dg += old[1] - db = (b - old[2])/sizerem - db += old[2] - sum += abs(db) - exactdata[x] = (dr, dg, db) - #print(new) - setpixel(dr, dg, db, x) - if sizerem == 1: - exactdata[x] = None - if sum == 0 and sizerem > 2: - sizerem = 2 - return sizerem - 1 - -def fadeorder(idxa,idxb,sizerem,r,g,b): - if sizerem < 1: - return 0 - global exactdata - drs = 0 - dgs = 0 - dbs = 0 - sum = 0 - for x in range(idxa,idxb): - if exactdata[x] is None: - exactdata[x] = data[x] - old = exactdata[x] - dr = (r - old[0]) - dg = (g - old[1]) - db = (b - old[2]) - drs += dr - dgs += dg - dbs += db - - drs /= sizerem - dgs /= sizerem - dbs /= sizerem - sum += abs(drs) + abs(dgs) + abs(dbs) - print(drs,dgs,dbs) - for x in range(idxa,idxb): - old = exactdata[x] - new = list(old) - if drs > 0: - if old[0] + drs > r: - new[0] = r - drs -= r - old[0] + def close(self): + time.sleep(0.5) + self.sender.stop() + return self + + def mapimage(self, image, fps=90): + while uptime() - self.start < 1/fps: + time.sleep(0.00001) + fprint(1 / (uptime() - self.start)) + self.start = uptime() + minsize = min(image.shape[0:2]) + leds_normalized2 = [(x * minsize, + y * minsize) + for x, y in self.leds_normalized] + + cv2.imshow("video", image) + cv2.waitKey(1) + + + #im_rgb = image #cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # OpenCV uses BGR format by default + avgx = 0 + avgy = 0 + for xx in range(len(leds_normalized2)): + led = leds_normalized2[xx] + x, y = int(round(led[0])), int(round(led[1])) + + if x < image.shape[1] and y < image.shape[0]: + #avgx += x + #avgy += y + color = tuple(image[y, x]) + self.setpixel(color[2]/2,color[1]/2,color[0]/2,xx) # swap b & r + #print(color) else: - new[0] = old[0] + drs - drs = 0 - if dgs > 0: - if old[1] + dgs > g: - new[1] = g - dgs -= g - old[1] - else: - new[1] = old[1] + dgs - dgs = 0 - if dbs > 0: - if old[2] + dbs > b: - new[2] = b - dbs -= b - old[2] - else: - new[2] = old[2] + dbs - dbs = 0 + #avgx += x + #avgy += y + self.setpixel(0,0,0,xx) + #avgx /= len(leds) + #avgy /= len(leds) + #print((avgx,avgy, max([led[0] for led in leds_adj]), max([led[1] for led in leds_adj]) , min(image.shape[0:2]) )) + self.fastsendall(self.data) + return self - if drs < 0: - if old[0] + drs < r: - new[0] = r - drs -= r - old[0] - else: - new[0] = old[0] + drs - drs = 0 - if dgs < 0: - if old[1] + dgs < g: - new[1] = g - dgs -= g - old[1] - else: - new[1] = old[1] + dgs - dgs = 0 - if dbs < 0: - if old[2] + dbs < b: - new[2] = b - dbs -= b - old[2] - else: - new[2] = old[2] + dbs - dbs = 0 + def mainloop(self, stmode, ring = -1, fps = 100, preview = False): + while uptime() - self.start < 1/fps: + time.sleep(0.00001) + fprint(1 / (uptime() - self.start)) + self.start = uptime() + if self.mode is not None: + self.setmode(stmode) + self.runmodes(ring) + if preview: + self.drawdata() + return self - if drs != 0 or dgs != 0 or dbs != 0: - exactdata[x] = new - setpixel(new[0],new[1],new[2],x) - - if sizerem == 1: - exactdata[x] = None + def drawdata(self): + #tmp = list() + #for x in len(leds): + # led = leds[x] + # tmp.append((led[0], led[1], data[x])) - if sum == 0 and sizerem > 2: - sizerem = 2 - return sizerem - 1 + x = [led[0] for led in self.leds] + y = [led[1] for led in self.leds] + colors = self.data + colors_normalized = [(x[0]/255, x[1]/255, x[2]/255) for x in colors] + # Plot the points + plt.scatter(x, y, c=colors_normalized) + + # Optional: add grid, title, and labels + plt.grid(True) + plt.title('Colored Points') + plt.xlabel('X') + plt.ylabel('Y') + plt.show() + plt.savefig("map3.png", dpi=50, bbox_inches="tight") + plt.clf() + return self + + def startup_animation(self, show): -def setpixel(r, g, b, num): - global data - global leds_size - # constrain values - if r < 0: - r = 0 - elif r > 255: - r = 255 - if g < 0: - g = 0 - elif g > 255: - g = 255 - if b < 0: - b = 0 - elif b > 255: - b = 255 + stmode = "Startup" + self.mainloop(stmode, preview=show) + while self.mode == "Startup": + self.mainloop(None, preview=show) + for x in range(54): + self.ringstatus[x][0] = False + self.mainloop(None, preview=show) - if leds_size[num] == 3: - data[num] = (int(r), int(g), int(b)) - elif leds_size[num] == 4: # cut out matching white and turn on white pixel instead - data[num] = (( int(r) - int(min(r,g,b)), int(g) - int(min(r,g,b)), int(b) - int(min(r,g,b)), int(min(r,g,b))) ) - else: - data[num] = (int(r), int(g), int(b)) - + for x in range(self.animation_time): + self.mainloop(None, preview=show) + self.clear_animations() + stmode = "StartupCheck" + self.mainloop(stmode, preview=show) + self.clear_animations() + return self -def close(): - global sender - time.sleep(0.5) - sender.stop() + def clear_animations(self): + for x in range(len(self.leds)): + self.exactdata[x] = None + return self -def mapimage(image, fps=90): - global start - while uptime() - start < 1/fps: - time.sleep(0.00001) - fprint(1 / (uptime() - start)) - start = uptime() - minsize = min(image.shape[0:2]) - leds_normalized2 = [(x * minsize, - y * minsize) - for x, y in leds_normalized] - - cv2.imshow("video", image) - cv2.waitKey(1) + def do_animation(self, stmode, ring=-1): + self.mainloop(stmode, ring, preview=show) + self.wait_for_animation(ring) + return self - - #im_rgb = image #cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # OpenCV uses BGR format by default - avgx = 0 - avgy = 0 - for xx in range(len(leds_normalized2)): - led = leds_normalized2[xx] - x, y = int(round(led[0])), int(round(led[1])) - - if x < image.shape[1] and y < image.shape[0]: - #avgx += x - #avgy += y - color = tuple(image[y, x]) - setpixel(color[2]/2,color[1]/2,color[0]/2,xx) # swap b & r - #print(color) - else: - #avgx += x - #avgy += y - setpixel(0,0,0,xx) - #avgx /= len(leds) - #avgy /= len(leds) - #print((avgx,avgy, max([led[0] for led in leds_adj]), max([led[1] for led in leds_adj]) , min(image.shape[0:2]) )) - global data - fastsendall(data) + def start_animation(self, stmode, ring=-1): + self.mainloop(stmode, ring, preview=show) + return self -def mainloop(stmode, ring = -1, fps = 100, preview = False): - global start - while uptime() - start < 1/fps: - time.sleep(0.00001) - fprint(1 / (uptime() - start)) - start = uptime() - if mode is not None: - setmode(stmode) - runmodes(ring) - if preview: - drawdata() - -def drawdata(): - #tmp = list() - #for x in len(leds): - # led = leds[x] - # tmp.append((led[0], led[1], data[x])) - - x = [led[0] for led in leds] - y = [led[1] for led in leds] - colors = data - colors_normalized = [(x[0]/255, x[1]/255, x[2]/255) for x in colors] - # Plot the points - plt.scatter(x, y, c=colors_normalized) - - # Optional: add grid, title, and labels - plt.grid(True) - plt.title('Colored Points') - plt.xlabel('X') - plt.ylabel('Y') - plt.show() - plt.savefig("map3.png", dpi=50, bbox_inches="tight") - plt.clf() - -def startup_animation(show): - - - stmode = "Startup" - mainloop(stmode, preview=show) - while mode == "Startup": - mainloop(None, preview=show) - for x in range(54): - ringstatus[x][0] = False - mainloop(None, preview=show) - - for x in range(animation_time): - mainloop(None, preview=show) - clear_animations() - stmode = "StartupCheck" - mainloop(stmode, preview=show) - clear_animations() - -def clear_animations(): - for x in range(len(leds)): - exactdata[x] = None - -def do_animation(stmode, ring=-1): - mainloop(stmode, ring, preview=show) - wait_for_animation(ring) - -def start_animation(stmode, ring=-1): - mainloop(stmode, ring, preview=show) - -def wait_for_animation(ring=-1): - while mode != "idle": - mainloop(None, ring, preview=show) + def wait_for_animation(self, ring=-1): + while self.mode != "idle": + self.mainloop(None, ring, preview=show) + return self if __name__ == "__main__": - init() + import matplotlib.pyplot as plt """cap = cv2.VideoCapture('badapple.mp4') while cap.isOpened(): ret, frame = cap.read() if not ret: - break - mapimage(frame, fps=30)""" - show = True + break + mapimage(frame, fps=30)""" + show = False ring = 1 - startup_animation(show) + ledsys = LEDSystem() + ledsys.startup_animation(show) for x in range(54): - ringstatus[x][0] = True - mainloop(None, preview=show) - for x in range(animation_time): - mainloop(None, preview=show) + ledsys.ringstatus[x][0] = True + ledsys.mainloop(None, preview=show) + for x in range(ledsys.animation_time): + ledsys.mainloop(None, preview=show) - do_animation("GrabA", 1) + ledsys.do_animation("GrabA", 1) - do_animation("GrabA", 5) - start_animation("GrabC", 1) + ledsys.do_animation("GrabA", 5) + ledsys.start_animation("GrabC", 1) - wait_for_animation(1) - do_animation("GrabC", 5) + ledsys.wait_for_animation(1) + ledsys.do_animation("GrabC", 5) - close() + ledsys.close() #sys.exit(0) diff --git a/map3.png b/map3.png index de82083..b00626d 100644 Binary files a/map3.png and b/map3.png differ diff --git a/requirements.txt b/requirements.txt index 55c1942..295e078 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,7 +19,7 @@ pandas pyarrow ghostscript pyzbar - +segno # Development matplotlib diff --git a/run.py b/run.py index d00a621..37b10d8 100755 --- a/run.py +++ b/run.py @@ -17,7 +17,7 @@ import signal import socket from flask import Flask, render_template, request import requests -import led_control +from led_control import LEDSystem import server import asyncio import json @@ -36,7 +36,7 @@ killme = None #pool = None serverproc = None camera = None - +ledsys = None to_server_queue = Queue() from_server_queue = Queue() @@ -47,6 +47,8 @@ def arm_start_callback(res): def led_start_callback(res): global led_ready led_ready = True + global ledsys + ledsys = res def camera_start_callback(res): global camera_ready @@ -233,11 +235,13 @@ def setup_server(pool): global camera pool.apply_async(ur5_control.init, (config["arm"]["ip"],), callback=arm_start_callback) - pool.apply_async(led_control.init, callback=led_start_callback) + global ledsys + ledsys = LEDSystem() + pool.apply_async(ledsys.init, callback=led_start_callback) #pool.apply_async(sensor_control.init, callback=sensor_start_callback) serverproc = Process(target=start_server_socket) serverproc.start() - + if led_ready is False: fprint("waiting for " + "LED controller initialization" + " to complete...", sendqueue=to_server_queue) while led_ready is False: diff --git a/setup-label-generator.py b/setup-label-generator.py index 0376975..e2ce67f 100644 --- a/setup-label-generator.py +++ b/setup-label-generator.py @@ -10,7 +10,7 @@ import opcode import os import distutils #distutils_path = os.path.join(os.path.dirname(opcode.__file__), 'distutils') -build_exe_options = {"include_msvcr": True, "packages": ["camelot", "setuptools"], "optimize": 0, "silent": True, "include_files": ["gs10030w64.exe"], "excludes": ["scipy", "torch"]} +build_exe_options = {"include_msvcr": True, "packages": ["camelot", "setuptools", "segno"], "optimize": 0, "silent": True, "include_files": ["gs10030w64.exe", "GothamCond-Medium.otf", "belden-logo-superhires.png"], "excludes": ["scipy", "torch"]} # base="Win32GUI" should be used only for Windows GUI app base = "console" diff --git a/test.pdf b/test.pdf deleted file mode 100644 index 033532c..0000000 Binary files a/test.pdf and /dev/null differ diff --git a/test2.pdf b/test2.pdf deleted file mode 100644 index 489e0e9..0000000 Binary files a/test2.pdf and /dev/null differ diff --git a/ur5_control.py b/ur5_control.py index 5622e79..38f9f58 100755 --- a/ur5_control.py +++ b/ur5_control.py @@ -319,7 +319,7 @@ def offset_gripper_angle(x, y, z, gripperangle=35, gripperlength=0.20+0.018, fli grippery += math.sin(gripperangle) * limb3 gripperx = math.sin(gripperangle) * gripperlength + limb3 * 2 gripperx -= (1-math.cos(gripperangle)) * limb3 - rz = - math.pi / 2 + rz = math.pi / 2 # flip the whole wrist return get_joints_from_xyz_abs(x, y, z-grippery, rx=gripperangle + math.radians(180), l3offset=-gripperx, ry=math.pi/2, rz=-rz) @@ -446,27 +446,22 @@ if __name__ == "__main__": #for i in np.linspace(0, 340, 340): # joints.append(goto_holder_index(24, 0.5, i)) #rob.movejs(joints, acc=1, vel=3) - # angle = 30 - # rob.movej(goto_holder_index(26, 0.1, angle), acc=2, vel=2) - # # rob.movej(goto_holder_index(32, 0.2, angle), acc=2, vel=2) - # rob.movej(goto_holder_index(38, 0.2, angle), acc=2, vel=2) - # rob.movej(goto_holder_index(26, 0.1, angle, flip=True), acc=2, vel=2) - # rob.movej(offset_gripper_angle(-0.3, -0.3, 0.4, flip=True), acc=2, vel=2) + angle = 30 + rob.movej(goto_holder_index(26, 0.1, angle), acc=2, vel=2) + time.sleep(1) + rob.movej(goto_holder_index(25, 0.1, angle), acc=2, vel=2) + time.sleep(1) + rob.movej(goto_holder_index(24, 0.1, angle, flip=True), acc=2, vel=2) + #rob.movej(goto_holder_index(32, 0.2, angle), acc=2, vel=2) + #rob.movej(goto_holder_index(38, 0.2, angle), acc=2, vel=2) + #rob.movej(goto_holder_index(25, 0.1, angle, flip=True), acc=2, vel=2) - # safe_move(0.1, 0.1, 0.1) - # safe_move(-0.3, -0.3, 0.1) - - # flip() - # flip() - - - - # rob.movej(goto_holder_index(25, 0.2, angle, flip=True), acc=2, vel=2) - # rob.movej(goto_holder_index(24, 0.0, angle, flip=True), acc=2, vel=2) - # time.sleep(1) - # rob.movej(goto_holder_index(25, 0.1, angle, flip=True), acc=2, vel=2) - # rob.movej(goto_holder_index(49, 0.1, angle), acc=2, vel=2) - # rob.movej(goto_holder_index(49, 0.1, angle, flip=True), acc=2, vel=2) + #rob.movej(goto_holder_index(25, 0.2, angle, flip=True), acc=2, vel=2) + #rob.movej(goto_holder_index(24, 0.1, angle, flip=True), acc=2, vel=2) + #time.sleep(1) + #rob.movej(goto_holder_index(25, 0.1, angle, flip=True), acc=2, vel=2) + #rob.movej(goto_holder_index(49, 0.1, angle), acc=2, vel=2) + #rob.movej(goto_holder_index(49, 0.1, angle, flip=True), acc=2, vel=2) # rob.movej(goto_holder_index(50, 0.1, angle, flip=True), acc=2, vel=2) # rob.movej(goto_holder_index(51, 0.1, angle, flip=True), acc=2, vel=2) # rob.movej(goto_holder_index(52, 0.1, angle, flip=True), acc=2, vel=2)