diff options
| author | Raymond Hogenson <rayhogenson@openmailbox.org> | 2016-09-27 17:04:45 -0400 |
|---|---|---|
| committer | Raymond Hogenson <rayhogenson@openmailbox.org> | 2016-09-27 17:04:45 -0400 |
| commit | 2266f5d72c634c66cc0bfbfa1e636f2556ab2ddb (patch) | |
| tree | efac86dab8b0e8fc2efb4a08f74b8a8f6d13064f /bridge.py | |
| parent | babf7bd8fc0b1879245a281e79915ed6278b8914 (diff) | |
| download | bridge-2266f5d72c634c66cc0bfbfa1e636f2556ab2ddb.tar.zst | |
Modify lights to select a random color
They should choose a random color in the correct interval and transition
gradually to it, however this code is currently untested.
Diffstat (limited to 'bridge.py')
| -rw-r--r-- | bridge.py | 116 |
1 files changed, 87 insertions, 29 deletions
@@ -1,7 +1,9 @@ #!/usr/bin/python """Simple demo of oscillating colors.""" from __future__ import division +import colorsys import lumiversepython +import math import random import time @@ -10,71 +12,127 @@ MIN_VALUE = 0 MAX_VALUE = 1 MAX_TIME = 4 MIN_TIME = 0.3 +MAX_HUE = 169 / 360 +MIN_HUE = 250 / 360 + +class Vector(object): + """N-dimensional vector class.""" + def __init__(self, *components): + """Create a vector from its components.""" + self.components = components + + def __add__(self, other): + """Add two vectors.""" + return Vector( + *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)) + ) + + def __mul__(self, other): + """Multiply a vector by a constant.""" + return Vector(*map(lambda x: x * other, self.components)) + + def __rmul__(self, other): + """Multiply a constant by a vector.""" + return self.__mul__(other) + + def __abs__(self): + """Return the 2-norm of the vector.""" + return math.sqrt(sum(map(lambda x: x * x, self.components))) + + +def HSV(Vector): + """HSV 3-vector.""" + def __init__(self, hue, saturation, value) + super().__init__(hue, saturation, value) + + def h(self): + """Return hue.""" + return self.components[0] + + def s(self): + """Return saturation.""" + return self.components[1] + + def v(self): + """Return value.""" + return self.components[2] + def get_all_lights(rig): """Return a list of all panels.""" - return [rig.select('$side={}[$sequence={}]'.format(j, i)) for j in ['top', 'bot'] for i in range(1, 200)] + return [ + rig.select('$side={}[$sequence={}]'.format(j, i)) + for j in ['top', 'bot'] for i in range(1, 200) + ] + + +def pick_HSV(): + """Return a random color in an appropriate interval.""" + hue = random.random() * (MAX_HUE - MIN_HUE) + MIN_HUE + saturation = random.random() + value = random.random() + return HSV(hue, saturation, value) -def restrict(low, x, high): - """Return a value low <= v <= high, and equal to x if possible.""" - return max(low, min(x, high)) +def transition(start, end, step): + """Return a vector equal to (end - start) * step + start.""" + return (end - start) * step + start 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) - rands = [random.randint(min_time, max_time) for _ in range(5)] - rand_binom = sum(rands) / 5 - #inverse = (rand_binom - (MAX_VALUE - MIN_VALUE) / 2) % (MAX_VALUE - MIN_VALUE) + MIN_VALUE return 1 / random.randint(min_time, max_time) +def HSV_to_RGB(h): + """Convert HSV to a 3-tuple of RGB.""" + return colorsys.hsv_to_rgb(h.h(), h.s(), h.v()) + + def demo(lights, rig): """Do some light things.""" light_status = [ { - 'is_increasing': True, - 'change': random_change(), + 'change': 0, 'light': light, - 'current_value': 0, + 'current value': Vector(0, 0, 0), + 'transitioning to': Vector(0, 0, 0), } for light in lights ] while True: for light_s in light_status: - is_increasing = light_s['is_increasing'] change = light_s['change'] light = light_s['light'] - current_value = light_s['current_value'] - new_value = restrict( - MIN_VALUE, current_value + change * (int(is_increasing) * 2 - 1), MAX_VALUE - ) - light.setRGBRaw(0, 0, new_value) - light_s['current_value'] = new_value - if new_value in [MIN_VALUE, MAX_VALUE]: - light_s['is_increasing'] = not is_increasing - light_s['change'] = random_change() + 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() + light_s['transitioning to'] = transitioning_to + new_color = transition(current_value, transitioning_to, change) + rgb = HSV_to_RGB(new_color) + light.setRGBRaw(*rgb) + light_s['current value'] = new_color rig.updateOnce() time.sleep(1 / FRAME_RATE) -def panels(lights, rig): - for light in lights: - light.setRGBRaw(1, 1, 1) - rig.updateOnce() - time.sleep(1) - light.setRGBRaw(0, 0, 0) - - def main(): """Run show.""" rig = lumiversepython.Rig('/home/teacher/Lumiverse/PBridge.rig.json') rig.init() lights = get_all_lights(rig) demo(lights, rig) - #panels(lights, rig) if __name__ == '__main__': main() |
