summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--DummyRig.py72
-rw-r--r--bridge.py70
-rw-r--r--color.py20
4 files changed, 121 insertions, 42 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0d20b64
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+*.pyc
diff --git a/DummyRig.py b/DummyRig.py
new file mode 100644
index 0000000..093a655
--- /dev/null
+++ b/DummyRig.py
@@ -0,0 +1,72 @@
+from Tkinter import *
+import re
+import threading
+import time
+
+def rgbToTkColor(r, g, b):
+ if not (0 <= r <= 1 and 0 <= g <= 1 and 0 <= b <= 1):
+ print "invalid r={}, g={}, b={}".format(r, g, b)
+ assert(False)
+
+ r_hex = int(r * 0xFF)
+ g_hex = int(g * 0xFF)
+ b_hex = int(b * 0xFF)
+ return "#{:02x}{:02x}{:02x}".format(r_hex, g_hex, b_hex)
+
+class DummyLight(object):
+ WIDTH_PX = 8
+ HEIGHT_PX = 20
+
+ def __init__(self, canvas):
+ self.canvas = canvas
+ self.color = (0, 0, 0)
+
+ def setRGBRaw(self, r, g, b):
+ self.color = (r, g, b)
+ self.canvas.itemconfig(self.rect_id, fill=rgbToTkColor(*self.color))
+
+
+class DummyRig(object):
+ def __init__(self, width, height):
+ self.width = width
+ self.height = height
+ self.margin = 5
+
+ def init(self):
+ self.root = Tk()
+ self.canvas = Canvas(self.root,
+ width=self.width*DummyLight.WIDTH_PX + self.margin*2,
+ height=self.height*DummyLight.HEIGHT_PX + self.margin*2)
+ self.canvas.pack()
+ self.root.resizable(width=0, height=0)
+
+ self.lights = [[DummyLight(self.canvas) for _ in xrange(self.height)]
+ for _ in xrange(self.width)]
+
+ self.rootThread = threading.Thread(target=self.root.mainloop)
+ self.rootThread.start()
+
+ self.initRects()
+
+ def select(self, pattern):
+ match = re.search("\$side=(.*?)\[\$sequence=(.*?)\]", pattern)
+ if match.group(1) == "bot":
+ y = 1
+ elif match.group(1) == "top":
+ y = 0
+
+ x = int(match.group(2)) - 1
+ return self.lights[x][y]
+
+ def updateOnce(self):
+ pass
+
+ def initRects(self):
+ for x in xrange(self.width):
+ for y in xrange(self.height):
+ light = self.lights[x][y]
+ x0 = self.margin + x * DummyLight.WIDTH_PX
+ y0 = self.margin + y * DummyLight.HEIGHT_PX
+ light.rect_id = self.canvas.create_rectangle(x0, y0, x0 + DummyLight.WIDTH_PX,
+ y0 + DummyLight.HEIGHT_PX,
+ width=1)
diff --git a/bridge.py b/bridge.py
index 22d8da2..64fc54f 100644
--- a/bridge.py
+++ b/bridge.py
@@ -3,23 +3,43 @@
from __future__ import division
import color
import colorsys
-import lumiversepython
+from DummyRig import DummyRig #import lumiversepython
import math
import random
import time
-FRAME_RATE = 44
+FRAME_RATE = 10 #44
MIN_VALUE = 0
MAX_VALUE = 1
MAX_TIME = 4
MIN_TIME = 0.3
-MAX_HUE = 169 / 360
+MAX_HUE = 230 / 360
MIN_HUE = 250 / 360
+class Panel(object):
+ def __init__(self, light):
+ self.light = light
+ self.current_color = color.RGB(0, 0, 0)
+ self.target_color = color.RGB(0, 0, 0)
+ self.delta = color.RGB(1, 1, 1)
+
+ def begin_transition(self, target_color, delta_ticks):
+ self.target_color = target_color
+ self.delta = (self.target_color - self.current_color) / delta_ticks
+
+ def tick(self):
+ self.current_color = self.current_color + self.delta
+ self.light.setRGBRaw(*self.current_color.components)
+
+ def transition_complete(self):
+ return abs(self.current_color - self.target_color) < abs(self.delta)
+
+
+
def get_all_lights(rig):
"""Return a list of all panels."""
return [
- rig.select('$side={}[$sequence={}]'.format(j, i))
+ Panel(rig.select('$side={}[$sequence={}]'.format(j, i)))
for j in ['top', 'bot'] for i in range(1, 200)
]
@@ -27,7 +47,7 @@ def get_all_lights(rig):
def pick_HSV():
"""Return a random color in an appropriate interval."""
hue = random.random() * (MAX_HUE - MIN_HUE) + MIN_HUE
- saturation = random.random()
+ saturation = random.random() * (1 - 0.63) + 0.63
value = random.random()
return color.HSV(hue, saturation, value)
@@ -38,44 +58,30 @@ def transition(start, end, step):
def random_change():
- """Return a random amount that a light should change each frame."""
- min_time = int(MIN_TIME * FRAME_RATE)
- max_time = int(MAX_TIME * FRAME_RATE)
- return 1 / random.randint(min_time, max_time)
+ """Return a random number of ticks for a light to change"""
+ min_ticks = int(MIN_TIME * FRAME_RATE)
+ max_ticks = int(MAX_TIME * FRAME_RATE)
+ return random.randint(min_ticks, max_ticks)
def demo(lights, rig):
"""Do some light things."""
- light_status = [
- {
- 'change': 0,
- 'light': light,
- 'current value': color.RGB(0, 0, 0),
- 'transitioning to': color.RGB(0, 0, 0),
- }
- for light in lights
- ]
while True:
- for light_s in light_status:
- change = light_s['change']
- light = light_s['light']
- current_value = light_s['current value']
- transitioning_to = light_s['transitioning to']
- if abs(transitioning_to - current_value) < change:
- change = random_change()
- light_s['change'] = change
- transitioning_to = pick_HSV().to_RGB()
- light_s['transitioning to'] = transitioning_to
- new_color = transition(current_value, transitioning_to, change)
- light.setRGBRaw(*new_color.components)
- light_s['current value'] = new_color
+ print "Tick"
+ for light in lights:
+ if light.transition_complete():
+ if( light == lights[0] ):
+ print "Transition complete!"
+ light.begin_transition(pick_HSV().to_RGB(), random_change())
+ light.tick()
+
rig.updateOnce()
time.sleep(1 / FRAME_RATE)
def main():
"""Run show."""
- rig = lumiversepython.Rig('/home/teacher/Lumiverse/PBridge.rig.json')
+ rig = DummyRig(200, 2) #lumiversepython.Rig('/home/teacher/Lumiverse/PBridge.rig.json')
rig.init()
lights = get_all_lights(rig)
demo(lights, rig)
diff --git a/color.py b/color.py
index 71fbaaf..a10073b 100644
--- a/color.py
+++ b/color.py
@@ -11,19 +11,19 @@ class Vector(object):
def __add__(self, other):
"""Add two vectors."""
- return Vector(
- *map(lambda x, y: x + y, zip(self.components, other.components))
+ return self.__class__(
+ *map(lambda (x, y): x + y, zip(self.components, other.components))
)
def __sub__(self, other):
"""Subtract two vectors."""
- return Vector(
- *map(lambda x, y: x - y, zip(self.components, other.components))
+ return self.__class__(
+ *map(lambda (x, y): x - y, zip(self.components, other.components))
)
def __mul__(self, other):
"""Multiply a vector by a constant."""
- return Vector(*map(lambda x: x * other, self.components))
+ return self.__class__(*map(lambda x: x * other, self.components))
def __rmul__(self, other):
"""Multiply a constant by a vector."""
@@ -33,16 +33,16 @@ class Vector(object):
"""Return the 2-norm of the vector."""
return math.sqrt(sum(map(lambda x: x * x, self.components)))
- def __div__(self, scalar):
+ def __truediv__(self, scalar):
"""Return self * 1 / scalar."""
return self * (1 / scalar)
-def HSV(Vector):
+class HSV(Vector):
"""HSV 3-vector."""
def __init__(self, hue, saturation, value):
"""Initialize with hue, saturation, and value."""
- super(Vector, self).__init__(hue, saturation, value)
+ super(HSV, self).__init__(hue, saturation, value)
def to_RGB(self):
"""Convert to an RGB vector."""
@@ -61,11 +61,11 @@ def HSV(Vector):
return self.components[2]
-def RGB(Vector):
+class RGB(Vector):
"""RGB 3-vector."""
def __init__(self, r, g, b):
"""Initialize with red green and blue."""
- super(Vector, self).__init__(r, g, b)
+ super(RGB, self).__init__(r, g, b)
def to_HSV(self):
"""Convert to HSV vector."""