summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgroup1 <f16_group1@pbridge.adm.cs.cmu.edu>2016-10-17 00:07:58 -0400
committergroup1 <f16_group1@pbridge.adm.cs.cmu.edu>2016-10-17 00:07:58 -0400
commit61b74608ce06bed0b9b7597af4ac7f6b9b3baac2 (patch)
treec284a027e35d8cb5043612bbd74cbfb9b22675fd
parent841c7607ffab66d208771c220f2e6a9193112234 (diff)
parentd996cea3e2c13487d2518a30089035c0fd88c0f4 (diff)
downloadbridge-61b74608ce06bed0b9b7597af4ac7f6b9b3baac2.tar.zst
Merge branch 'master' of https://github.com/rayhogenson/bridge
Conflicts: ShowRunner.py
-rw-r--r--ShowRunner.py2
-rwxr-xr-xtwinkle.py241
2 files changed, 144 insertions, 99 deletions
diff --git a/ShowRunner.py b/ShowRunner.py
index 1ec1c87..61c0cf6 100644
--- a/ShowRunner.py
+++ b/ShowRunner.py
@@ -1,6 +1,7 @@
from bridge import Bridge
from fish_show import FishShow
from sunrise import SunriseShow
+from twinkle import TwinkleShow
from constants import *
import sys
@@ -10,6 +11,7 @@ from run import server_thread, send_queue, recv_queue
def run_show():
server_thread.start()
bridge = Bridge()
+ TwinkleShow(bridge, send_queue=recv_queue, recv_queue=send_queue).run(framerate=FRAME_RATE)
SunriseShow(bridge, send_queue=recv_queue, recv_queue=send_queue).run(framerate=FRAME_RATE)
FishShow(bridge, send_queue=recv_queue, recv_queue=send_queue).run(framerate=FRAME_RATE)
print "done!"
diff --git a/twinkle.py b/twinkle.py
index a2cb3d2..6c788e9 100755
--- a/twinkle.py
+++ b/twinkle.py
@@ -1,112 +1,155 @@
-#!/usr/bin/python2
-"""Simple demo of twinkle lights."""
+"""Rendering classes and helper functions."""
from __future__ import division
import color
+import random
import constants
-#from DummyRig import DummyRig
-from fish_render import *
-import fish_render
from constants import *
-import time
-import random
-try:
- import lumiversepython
-except ImportError:
- have_lumiversepython = False
-else:
- have_lumiversepython = True
+import math
+from show import Show
+
+class ShootingStar(object):
+ """Object displayed on the bridge, probably a fish."""
+ def __init__(self):
+ """Create fish with default parameters."""
+ self.x = random.random() * BRIDGE_WIDTH
+ self.y = random.random() * 1.5
+ self.width = 5
+ self.height = 0.5
+ self.color = color.RGB(1, 1, 1)
+ if random.random() >= 0.5:
+ self.speed = 8
+ else:
+ self.speed = -8
-def get_all_lights(rig):
- """Return a list of all panels."""
- return [
- [
- fish_render.Light(
- x, int(y == 'top'),
- rig.select('$side={y}[$sequence={x}]'.format(y=y, x=x))
- ) for y in ('top', 'bot')
- ] for x in xrange(1, 200)
- ]
+ def update(self):
+ self.x += self.speed
+ self.speed *= 0.9
+ return abs(self.speed) > 1 and self.x < BRIDGE_WIDTH
-def flip():
- """Return 0 with 99.9% prob. & 1 with .1% prob."""
- # should be black most of the time
- return random.random() < 0.0005
+class Light(object):
+ """Represent a bridge light and its state."""
+ def __init__(self, x, y, light):
+ """Store all facts about a light."""
+ self.light = light
+ self.color = color.black
+ self.result_color = self.color
+ self.transitioning_to = self.color
+ self.step = 0
+ self.on = False
+ self.increasing = False
+ self.x = x
+ self.y = y
+ self.fade_step = 0
-def twinkle(lights, rig):
- """Try to do some light things."""
- light_status = [
- {
- 'is_increasing': True,
- 'is_on': False,
- 'change': random_change(),
- 'light': light,
- 'intensity': 0,
- }
- for light_col in lights for light in light_col
- ]
- shooting_stars = list()
- while True:
- if random.random() < 1:
- shooting_stars.append([random.randint(1, 180), random.random() < 0.5, 0])
- for light_s in light_status:
- is_increasing = light_s['is_increasing']
- is_on = light_s['is_on']
- change = light_s['change']
- light = light_s['light']
- intensity = light_s['intensity']
- # R and G are either 0 or 1
- if not is_on:
- if flip():
- is_on = True
- is_increasing = True
- change = 1.5 / FRAME_RATE
- light_s['is_on'] = is_on
- light_s['is_increasing'] = is_increasing
- light_s['change'] = change
+ def update_base(self):
+ """Change color depending on where the fish is."""
+ if not self.on and random.random() < 0.0005:
+ self.transitioning_to = color.RGB(1, 1, 1)
+ self.step = abs(self.transitioning_to - self.color) / (FRAME_RATE / 2)
+ self.increasing = True
+ self.on = True
+ self.color = transition(self.color, self.transitioning_to, self.step)
+ elif self.on:
+ if abs(self.transitioning_to - self.color) <= self.step:
+ if self.increasing == True:
+ self.transitioning_to = color.RGB(0, 0, 0)
+ self.step = abs(self.transitioning_to - self.color) / (FRAME_RATE / 2)
+ self.increasing = False
else:
- continue
- intensity = clamp(0, intensity + change * (int(is_increasing) * 2 - 1), 1)
- light.light.setRGBRaw(intensity, intensity, intensity)
- light_s['intensity'] = intensity
- if intensity == 0:
- light_s['is_on'] = False
- if intensity == 1:
- light_s['is_increasing'] = False
- for i, star in enumerate(shooting_stars):
- star[2] += 1
- if star[2] > 10:
- for dx in range(-6, 7):
- light_status[star[0] + dx]['light'].light.setRGBRaw(0, 0, 0)
- del shooting_stars[i]
- continue
- star[0] += int(star[1]) * 2 - 1
- for dx in range(-6, 7):
- intensity = 1 - 1 / 6 * abs(dx)
- light_status[star[0] + dx]['light'].light.setRGBRaw(intensity, intensity, intensity)
- rig.updateOnce()
- time.sleep(1 / FRAME_RATE)
+ self.increasing = False
+ self.on = False
+ self.color = transition(self.color, self.transitioning_to, self.step)
+
+ self.result_color = self.color
+
+ def update_star(self, star):
+ coverage = compute_coverage(star, self.x, self.y)
+ self.result_color = coverage * star.color + (1 - coverage) * self.result_color
+
+ def blit(self):
+ self.light.setRGBRaw(
+ *map(lambda x: clamp(0, x, 1), self.result_color.components)
+ )
+
+
+
+
+ def fade_to_black(self, steps):
+ hue = self.color.to_HSV().h()
+ sat = self.color.to_HSV().s()
+ value = self.color.to_HSV().v()
+ new_color = color.HSV(hue, sat, value - value / steps * self.fade_step).to_RGB()
+ self.fade_step += 1
+ self.light.setRGBRaw(*map(lambda x: clamp(0, x, 1), new_color.components))
+
+
+class TwinkleShow(Show):
+ def init(self):
+ self.lights = [[Light(x, y, self.bridge.get_light(x, y))
+ for y in xrange(self.bridge.HEIGHT)]
+ for x in xrange(self.bridge.WIDTH)]
+ #self.sun = Sun()
+ self.stars = set()
+ self.tick_count = 0
+
+
+ def update(self):
+ if self.tick_count > 1000:
+ fade_time = 3 # sec
+ if self.tick_count > 1000 + fade_time * FRAME_RATE:
+ self.stop()
+ return
+ for col in self.lights:
+ for light in col:
+ light.fade_to_black(fade_time * FRAME_RATE)
+ else:
+ if random.random() < 0.01:
+ print "Adding star"
+ self.stars.add(ShootingStar())
+ for col in self.lights:
+ for light in col:
+ light.update_base()
+
+ for star in list(self.stars):
+ if not star.update():
+ self.stars.remove(star)
+
+ for x in xrange(int(star.x), int(star.x+star.width+1)):
+ if x < len(self.lights):
+ for light in self.lights[x]:
+ light.update_star(star)
+
+ for col in self.lights:
+ for light in col:
+ light.blit()
+
+ self.tick_count += 1
+ print self.tick_count
-def sunrise(lights, rig):
- #rig.select('$side={y}[$sequence={x}]'.format(y=y, x=x))
- rig.select("$side=top[$panel=27|$panel=28]")
- rig.updateOnce()
- time.sleep(1)
+def compute_coverage(fish, x, y):
+ """Calculate the coverage of a fish over a box."""
+ middle_of_fish = fish.x + fish.width / 2
+ middle_of_panel = x + 0.5
+ diff = abs(middle_of_fish - middle_of_panel) / (fish.width / 2)
+ scale = 1 - diff
+ min_x = min(max(x, fish.x), x + 1)
+ max_x = max(min(x+1, fish.x + fish.width), x)
+ min_y = min(max(y, fish.y), y + 1)
+ max_y = max(min(y+1, fish.y + fish.height), y)
+ coverage = (max_x - min_x) * (max_y - min_y)
+ return coverage * scale
-def main():
- """Run show."""
- if have_lumiversepython:
- rig = lumiversepython.Rig('/home/teacher/Lumiverse/PBridge.rig.json')
- else:
- rig = DummyRig(200, 2)
- rig.init()
- lights = get_all_lights(rig)
- #for light in lights:
- # light.setRGBRaw(0, 0, 0)
- rig.updateOnce()
- time.sleep(3)
- twinkle(lights, rig)
+def transition(start, end, step):
+ """Return a vector equal to (end - start) * step + start."""
+ if start == end:
+ return start
+ diff_vector = end - start
+ step_vector = diff_vector / abs(diff_vector) * step
+ result = step_vector + start
+ return result
-if __name__ == '__main__':
- main()
+def clamp(low, x, high):
+ """Return v such that low <= v <= high and |x - v| is minimal."""
+ return max(low, min(x, high))