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)