aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Daniel <dmt@daniel-desktop.(none)>2011-01-29 18:54:50 -0800
committerGravatar Daniel <dmt@daniel-desktop.(none)>2011-01-29 18:54:50 -0800
commitff07b18748c64243c1c6bc62f489bfd03205d13a (patch)
treedb95373a3511be0dd1e700a78e9f1ea7320769a4
parent83931a3c8e65b4018e98b4986458d1df7172ab91 (diff)
parent277a5143165d2553ce5e97f151cc6b3cea426468 (diff)
Merge branch 'master' of github.com:rcoh/SmootLight
-rwxr-xr-xLightInstallation.py2
-rw-r--r--Profile.py2
-rw-r--r--behaviors/Accelerate.xml2
-rw-r--r--behaviors/AddPixelEvent.py2
-rw-r--r--behaviors/ControllerOSC.py62
-rw-r--r--behaviors/Deccelerate.xml9
-rw-r--r--behaviors/DimColor.xml2
-rw-r--r--behaviors/EchoBehavior.py5
-rw-r--r--behaviors/Expand.py3
-rw-r--r--behaviors/ExpandingColorZones.py21
-rw-r--r--behaviors/Flasher.py41
-rw-r--r--behaviors/MITDoors.py8
-rw-r--r--behaviors/MobileShakeBehavior.py29
-rw-r--r--behaviors/MoveBehavior.py7
-rw-r--r--behaviors/RandomSetBrightColorBehavior.py14
-rw-r--r--behaviors/ResponseMover.py8
-rw-r--r--behaviors/RiseFall.py6
-rw-r--r--behaviors/Sink.py42
-rwxr-xr-xbehaviors/SmootWind.py43
-rw-r--r--behaviors/SynchTest.py12
-rw-r--r--behaviors/TouchOSC.py5
-rw-r--r--behaviors/XYMove.py1
-rw-r--r--config/6thFloor.xml2
-rw-r--r--config/6thFloorOSC.xml91
-rw-r--r--config/Demo.xml227
-rw-r--r--config/FireflyDemo.xml163
-rwxr-xr-xconfig/HTMLTest.xml58
-rw-r--r--config/Jennifer.xml129
-rw-r--r--config/Kuan.xml108
-rw-r--r--config/MobileTest.xml28
-rwxr-xr-xconfig/SmootWindTest.xml181
-rw-r--r--config/SynchTest.xml39
-rwxr-xr-xinputs/HTMLInput.py29
-rw-r--r--inputs/OSCInput.py4
-rw-r--r--inputs/PygameInput.py7
-rw-r--r--inputs/RandomLocs.py32
-rw-r--r--inputs/TCPInput.py16
-rw-r--r--pixelcore/Pixel.py4
-rw-r--r--pixelcore/Screen.py19
-rw-r--r--pixelevents/SynchTestEvent.py15
-rwxr-xr-xpixelmappers/WindGaussianMapper.py18
-rw-r--r--renderers/IndoorRenderer.py7
-rwxr-xr-xtestosc.py36
-rwxr-xr-xtests/testosc.py (renamed from oscserver.py)0
-rw-r--r--util/ColorOps.py17
-rw-r--r--util/Geo.py6
-rw-r--r--util/NetworkOps.py6
-rw-r--r--util/PacketComposition.py15
48 files changed, 1453 insertions, 130 deletions
diff --git a/LightInstallation.py b/LightInstallation.py
index 24ad8b1..c1f01e8 100755
--- a/LightInstallation.py
+++ b/LightInstallation.py
@@ -139,7 +139,7 @@ class LightInstallation(object):
def mainLoop(self):
lastLoopTime = clock.time()
- refreshInterval = 30
+ refreshInterval = 30
while not self.dieNow: #dieNow is set if one of its constituents sends a die request.
loopStart = clock.time()
responses = self.evaluateBehaviors()
diff --git a/Profile.py b/Profile.py
index 2f180c9..daabb6b 100644
--- a/Profile.py
+++ b/Profile.py
@@ -1,4 +1,4 @@
import cProfile
from LightInstallation import main
-command = """main(['', 'config/6thFloor.xml'])"""
+command = """main(['', 'config/Kuan.xml'])"""
cProfile.runctx(command, globals(), locals(), filename="smootlight.profile")
diff --git a/behaviors/Accelerate.xml b/behaviors/Accelerate.xml
index f9de077..c78195b 100644
--- a/behaviors/Accelerate.xml
+++ b/behaviors/Accelerate.xml
@@ -3,6 +3,6 @@
<Args>
<ParamType>Sensor</ParamType>
<ParamName>StepSize</ParamName>
- <ParamOp>{val}*1.1</ParamOp>
+ <ParamOp>{val}*1.01</ParamOp>
</Args>
</Behavior>
diff --git a/behaviors/AddPixelEvent.py b/behaviors/AddPixelEvent.py
index 821f432..da3f7c2 100644
--- a/behaviors/AddPixelEvent.py
+++ b/behaviors/AddPixelEvent.py
@@ -21,8 +21,6 @@ class AddPixelEvent(Behavior):
ret = []
for sensory in sensors:
outDict = {}
- if not 'Location' in sensory:
- pdb.set_trace()
outDict[Strings.LOCATION] = sensory[Strings.LOCATION]
settingsDict = dict(self.argDict)
settingsDict['Color'] = sensory['Color']
diff --git a/behaviors/ControllerOSC.py b/behaviors/ControllerOSC.py
new file mode 100644
index 0000000..05d2e7d
--- /dev/null
+++ b/behaviors/ControllerOSC.py
@@ -0,0 +1,62 @@
+from operationscore.Behavior import *
+from logger import main_log
+#import util.ColorOps as color
+import colorsys
+from numpy import array
+import pdb
+import util.ComponentRegistry as compReg
+
+speedfactor = 15
+vel_decay = .9
+
+def constrainLocation(v,c):
+ if v[0] > c[0]:
+ v[0] = c[0]
+ elif v[0]<0:
+ v[0] = 0
+
+ if v[1] > c[1]:
+ v[1] = c[1]
+ elif v[1]<0:
+ v[1] = 0
+
+ return v
+
+class ControllerOSC(Behavior):
+ def behaviorInit(self):
+ self.xy = array((0,0))
+ self.v_xy = array((0,0))
+ self.v_decay = vel_decay
+
+ self.start_hsv = [0,1,1]
+ self.dest_hsv = [0,1,1]
+ self.ssize = compReg.getComponent('Screen').getSize()[-2:] #896 x 310
+
+ def processResponse(self, sensorInputs, recursiveInputs):
+ ret = []
+ if sensorInputs:
+ data = sensorInputs[-1]#for data in sensorInputs:
+ if data['Path'] == '/sixaxis/xy':
+ #try:
+ x = data['Value'][0]
+ y = data['Value'][1]
+ if y < 0:
+ self.start_hsv[1] = 1.0+y #s
+ else:
+ self.start_hsv[2] = 1.0-y
+ self.start_hsv[0] = (x+1)/2.
+ elif data['Path'] == '/sixaxis/lrud':
+ val=data['Value']
+ vy = val[3]-val[2]
+ vx = val[1]-val[0]
+ #pdb.set_trace()
+ #self.v_xy = (val[1]*ssize[0], (1.0-val[0])*ssize[1])
+ self.v_xy = array((vx, vy)) * speedfactor
+ else:
+ main_log.error('Sensor Inputs: ' + str(sensorInputs))
+ self.xy = self.xy + self.v_xy
+ constrainLocation(self.xy,self.ssize)
+ self.v_xy *= self.v_decay
+ ret.append({'Color':[i*255. for i in colorsys.hsv_to_rgb(*self.start_hsv)],'Location':(int(self.xy[0]), int(self.xy[1]))})
+
+ return (ret, [])
diff --git a/behaviors/Deccelerate.xml b/behaviors/Deccelerate.xml
new file mode 100644
index 0000000..e64e61d
--- /dev/null
+++ b/behaviors/Deccelerate.xml
@@ -0,0 +1,9 @@
+
+<Behavior>
+ <Class>behaviors.ModifyParam</Class>
+ <Args>
+ <ParamType>Sensor</ParamType>
+ <ParamName>StepSize</ParamName>
+ <ParamOp>{val}*.98</ParamOp>
+ </Args>
+</Behavior>
diff --git a/behaviors/DimColor.xml b/behaviors/DimColor.xml
index 58b0673..ef98fee 100644
--- a/behaviors/DimColor.xml
+++ b/behaviors/DimColor.xml
@@ -3,6 +3,6 @@
<Args>
<ParamType>Sensor</ParamType>
<ParamName>Color</ParamName>
- <ParamOp>[chan*.95 for chan in {val}]</ParamOp>
+ <ParamOp>[chan*.98 for chan in {val}]</ParamOp>
</Args>
</Behavior>
diff --git a/behaviors/EchoBehavior.py b/behaviors/EchoBehavior.py
index 6ef4fcb..c4af7c0 100644
--- a/behaviors/EchoBehavior.py
+++ b/behaviors/EchoBehavior.py
@@ -9,6 +9,9 @@ class EchoBehavior(Behavior):
for sensory in sensorInputs:
outDict = {}
outDict[Strings.LOCATION] = sensory[Strings.LOCATION]
- outDict['Color'] = (255,0,0)
+ if self['Color'] != None:
+ outDict['Color'] = self['Color']
+ else:
+ outDict['Color'] = (255,0,0)
ret.append(outDict)
return (ret, [])
diff --git a/behaviors/Expand.py b/behaviors/Expand.py
index 323e71f..f017c16 100644
--- a/behaviors/Expand.py
+++ b/behaviors/Expand.py
@@ -15,7 +15,8 @@ class Expand(Behavior):
data = dict(data)
data['Left'] -= data['ExpandRate']
data['Right'] += data['ExpandRate']
- data['Location'] = "{x}>" + str(data['Left']) + ", {x}<" + str(data['Right'])
+ data['Location'] = "{x}>" + str(data['Left']) + ", {x}<" +\
+ str(data['Right'])+", {y}<50"
ret.append(data)
return (ret, [])
diff --git a/behaviors/ExpandingColorZones.py b/behaviors/ExpandingColorZones.py
new file mode 100644
index 0000000..75be761
--- /dev/null
+++ b/behaviors/ExpandingColorZones.py
@@ -0,0 +1,21 @@
+from operationscore.Behavior import *
+from logger import main_log
+class ExpandingColorZones(Behavior):
+ def behaviorInit(self):
+ self.mapping = {'s001':[(132,0),(255,0,0)], 's002':[(400,0), (0,255,0)],
+ 's003':[(668,0),
+ (0,0,255)]}
+ self.mappingkey = 'data'
+ def processResponse(self, sensorInputs, recursiveInputs):
+ ret = []
+ for data in sensorInputs:
+ print data
+ data = dict(data)
+ if self.mappingkey in data:
+ try:
+ data['Location'], data['Color'] =\
+ self.mapping[data[self.mappingkey]]
+ ret.append(data)
+ except:
+ main_log.warn('Bad mapping key. Expanding Color Zones.')
+ return (ret,[])
diff --git a/behaviors/Flasher.py b/behaviors/Flasher.py
new file mode 100644
index 0000000..1d79d41
--- /dev/null
+++ b/behaviors/Flasher.py
@@ -0,0 +1,41 @@
+
+from operationscore.Behavior import *
+import util.ColorOps as colorops
+import pdb
+class Flasher(Behavior):
+ """Implements a pulsing/flashing behavior.
+ Jim Salem: jsalem@gmail.com
+
+ Args:
+ Factor - The speed of flashing. Must be b/w 0 and 1. Default is .95
+ """
+ def processResponse(self, sensorInputs, recursiveInputs):
+ ret = []
+ for response in sensorInputs:
+ # Get the multiplier
+ if self['Factor'] != None:
+ factor = self['Factor']
+ else:
+ factor = 0.95
+ # Initialize the first time
+ if not 'FireflyStartColor' in response:
+ response['FireflyValue'] = 1.0
+ response['FireflyDir'] = 1
+ response['FireflyStartColor'] = response['Color'];
+ else:
+ # Update the current value
+ if response['FireflyDir'] == 1:
+ response['FireflyValue'] = response['FireflyValue'] * factor
+ if response['FireflyValue'] <= 0.01:
+ response['FireflyValue'] = 0.01
+ response['FireflyDir'] = 0
+ else:
+ response['FireflyValue'] = response['FireflyValue'] / factor
+ if response['FireflyValue'] >= 1.0:
+ response['FireflyValue'] = 1.0
+ response['FireflyDir'] = 1
+
+ # Compute the color
+ response['Color'] = colorops.multiplyColor(response['FireflyStartColor'], response['FireflyValue'])
+ ret.append(response)
+ return (ret, []) #no direct ouput
diff --git a/behaviors/MITDoors.py b/behaviors/MITDoors.py
index d602a55..cee47f0 100644
--- a/behaviors/MITDoors.py
+++ b/behaviors/MITDoors.py
@@ -1,4 +1,6 @@
from operationscore.Behavior import *
+import math
+import util.ComponentRegistry as compReg
class MITDoors(Behavior):
"""MITDoors is a case-specific behavior to map keypresses to specific locations. Written for
Kuan 1/26/11 by RCOH"""
@@ -6,6 +8,11 @@ class MITDoors(Behavior):
def behaviorInit(self):
self.keymapping = {'q':[2,19], 'w':[22,36], 'e':[37,49], 'r':[52,69], 't':[76,91], 'y':[94,105],
'u':[106,117], 'i':[123,154], 'o':[158,161], 'p':[164,167], '[':[172,184]}
+ screenWidth = compReg.getComponent('Screen').getSize()[2] #(minx, miny,maxx, maxy)
+ maxKey = max([max(self.keymapping[v]) for v in self.keymapping])
+ mult = screenWidth / float(maxKey)
+ for k in self.keymapping:
+ self.keymapping[k] = [int(val*mult) for val in self.keymapping[k]]
def processResponse(self, sensorInputs, recursiveInputs):
ret = []
for data in sensorInputs:
@@ -16,5 +23,6 @@ class MITDoors(Behavior):
data['Left'], data['Right'] = bounds
data['Bottom'] = self['Bottom']
data['Location'] = (sum(bounds) / 2., self['Bottom'])
+ data['Oscillate'] = False
ret.append(data)
return (ret, [])
diff --git a/behaviors/MobileShakeBehavior.py b/behaviors/MobileShakeBehavior.py
index e25e929..b05cb5f 100644
--- a/behaviors/MobileShakeBehavior.py
+++ b/behaviors/MobileShakeBehavior.py
@@ -1,17 +1,26 @@
from operationscore.Behavior import *
+import util.ComponentRegistry as compReg
import util.Strings as Strings
class MobileShakeBehavior(Behavior):
+ def behaviorInit(self):
+ self.mapper = None
+
def processResponse(self, sensorInputs, recursiveInputs):
+ if self.mapper == None:
+ try:
+ self.mapper = compReg.getComponent('mobilegaussmap')
+ except KeyError:
+ pass
+
#print sensorInputs
- ret = []
for sInput in sensorInputs:
- outDict = dict(sInput)
- if 'type' in sInput and sInput['type'] == 2:
- outDict['Location'] = '{x}>' + str(0) + ',{y}>' + str(0)
- outDict['Color'] = [sInput['r'], sInput['g'], sInput['b']]
- else: # dumb invisible pixel
- outDict['Location'] = (-1, -1)
- outDict['Color'] = [0, 0, 0]
- ret.append(outDict)
- return (ret, recursiveInputs)
+ if 'Shake' in sInput and sInput['Shake'] == 1:
+ #print 'increase!'
+ self.mapper.argDict['Width'] += 30
+ #self.mapper.argDict['CutoffDist'] += 20
+ sInput['Shake'] = 0
+ print 'Width:' + str(compReg.getComponent('mobilegaussmap').argDict['Width'])
+ #print 'CutoffDist: '+ str(compReg.getComponent('mobilegaussmap').argDict['CutoffDist'])
+
+ return (sensorInputs, recursiveInputs)
diff --git a/behaviors/MoveBehavior.py b/behaviors/MoveBehavior.py
index e504ca9..6e7fc6a 100644
--- a/behaviors/MoveBehavior.py
+++ b/behaviors/MoveBehavior.py
@@ -19,12 +19,13 @@ class MoveBehavior(Behavior):
currDict = dict(currRecLoc)
for sensorInput in sensorInputs:
if 'type' in sensorInput and sensorInput['type'] == 1:
+ currDict['Shake'] = 0
currDict['Location'] = (currDict['Location'][0] - sensorInput['x'] * self['XStep'], \
currDict['Location'][1] + sensorInput['y'] * self['YStep'])
currDict['Color'] = [sensorInput['r'], sensorInput['g'], sensorInput['b']]
- #elif sensorInput['type'] == 2:
- # currDict['Shake'] = 1
- # currDict['Force'] = sensorInput['force']
+ elif sensorInput['type'] == 2:
+ currDict['Shake'] = 1
+ #currDict['Force'] = sensorInput['force']
ret.append(currDict)
#print ret
return (ret, ret)
diff --git a/behaviors/RandomSetBrightColorBehavior.py b/behaviors/RandomSetBrightColorBehavior.py
new file mode 100644
index 0000000..f278858
--- /dev/null
+++ b/behaviors/RandomSetBrightColorBehavior.py
@@ -0,0 +1,14 @@
+from operationscore.Behavior import *
+import util.ColorOps as color
+import pdb
+import colorsys
+import random
+class RandomSetBrightColorBehavior(Behavior):
+ """Sets a random color that is bright."""
+ def processResponse(self, sensorInputs, recursiveInputs):
+ ret = []
+ for sensory in sensorInputs:
+ newDict = dict(sensory)
+ newDict['Color'] = color.randomBrightColor()
+ ret.append(newDict)
+ return (ret, [])
diff --git a/behaviors/ResponseMover.py b/behaviors/ResponseMover.py
index 59e353a..3d559df 100644
--- a/behaviors/ResponseMover.py
+++ b/behaviors/ResponseMover.py
@@ -7,11 +7,5 @@ class ResponseMover(Behavior):
modulates the location."""
def processResponse(self, sensorInputs, recursiveInputs):
- newResponses = sensorInputs
- ret = []
- for recurInput in recursiveInputs:
- outDict = dict(recurInput)
- ret.append(outDict)
- ret += newResponses
- return (ret, ret)
+ return (recursiveInputs, recursiveInputs+sensorInputs)
diff --git a/behaviors/RiseFall.py b/behaviors/RiseFall.py
index 109cd10..eea2283 100644
--- a/behaviors/RiseFall.py
+++ b/behaviors/RiseFall.py
@@ -29,7 +29,13 @@ class RiseFall(Behavior):
data['Right'] = data['Location'][0]+data['Width']/2.
currentTime = timeOps.time()
deltaTime = currentTime-data['StartTime']
+ #if data['Oscillate'] == True:
data['Height'] = data['MaxHeight']*math.sin(deltaTime/data['Period']*(math.pi*2))
+ #else:
+ # data['Height'] = data['MaxHeight']
+ #if (currentTime-data['StartTime']) > data['Period']:
+ # del data['StartTime']
+
data['Location'] = "{x}>"+str(data['Left']) + ", " +\
"{x}<"+str(data['Right'])+", {y}<" + str(data['Bottom']) + ",\
{y}>"+str(data['Bottom']-data['Height'])
diff --git a/behaviors/Sink.py b/behaviors/Sink.py
new file mode 100644
index 0000000..52d0be2
--- /dev/null
+++ b/behaviors/Sink.py
@@ -0,0 +1,42 @@
+
+from operationscore.Behavior import *
+import math
+import util.TimeOps as timeOps
+#Required Args:
+#Period (ms), MaxHeight, Width
+class Sink(Behavior):
+ """RiseFall is a behavior that creates a rising and falling column of light. Specify:
+ <MaxHeight> -- the maximum height that it rises to.
+ <Width> -- the width of the column OR <Left> and <Right>
+ <Period> -- the period of oscillation in ms
+
+ Designed to be used as part of a recursive hook.
+ """
+
+ def processResponse(self, sensorInputs, recurInputs):
+ ret = []
+ for data in sensorInputs:
+ #first time with behavior:
+ data = dict(data)
+ if not 'StartTime' in data:
+ data['StartTime'] = timeOps.time()
+ data['Period'] = self['Period']
+ data['MaxHeight'] = self['MaxHeight'] #Consider just using +=
+ if not 'Bottom' in data:
+ data['Bottom'] = data['Location'][1]
+ if 'Width' in self: #TODO: improve
+ data['Width'] = self['Width']
+ data['Left'] = data['Location'][0]-data['Width']/2.
+ data['Right'] = data['Location'][0]+data['Width']/2.
+ currentTime = timeOps.time()
+ deltaTime = currentTime-data['StartTime']
+ data['Height'] = data['MaxHeight']*math.cos(deltaTime/data['Period']*(math.pi*2))
+
+ data['Location'] = "{x}>"+str(data['Left']) + ", " +\
+ "{x}<"+str(data['Right'])+", {y}<" + str(data['Bottom']) + ",\
+ {y}>"+str(data['Bottom']-data['Height'])
+
+ ret.append(data)
+ return (ret, [])
+
+
diff --git a/behaviors/SmootWind.py b/behaviors/SmootWind.py
new file mode 100755
index 0000000..804183c
--- /dev/null
+++ b/behaviors/SmootWind.py
@@ -0,0 +1,43 @@
+from operationscore.Behavior import *
+import util.ComponentRegistry as compReg
+import random
+
+class SmootWind(Behavior):
+ def behaviorInit(self):
+ self.mapper = None
+ self.xFor = None
+
+ def processResponse(self, sensorInputs, recursiveInputs):
+ if self.mapper == None:
+ try:
+ self.mapper = compReg.getComponent('windgaussmap')
+ except KeyError:
+ pass
+ if self.xFor == None:
+ try:
+ self.xFor = compReg.getComponent('xfor')
+ except KeyError:
+ pass
+
+ for sensory in sensorInputs:
+ print sensory
+ # input[0] is windspeed, [1] is dir
+ if 0 in sensory and 1 in sensory:
+ windSpeed = sensory[0]
+ windDir = sensory[1]
+ #print self.mapper.argDict
+ self.mapper.argDict['Width'] = self.mapper.argDict['Width']+float(windSpeed)*2+20
+ self.xFor.argDict['ParamOp'] = self.xFor.argDict['ParamOp']+float(windSpeed)*3+10*random.random();
+ #print 'Width: ' + str(self.mapper.argDict['Width'])
+ #print 'xFor: ' + str(self.xFor.argDict['ParamOp'])
+
+ elif 'Key' in sensory:
+ if sensory['Key'] == 273:
+ self.mapper.argDict['Width'] = self.mapper.argDict['Width']+10;
+ self.xFor.argDict['ParamOp'] = self.xFor.argDict['ParamOp']+5;
+
+ elif sensory['Key'] == 274:
+ self.mapper.argDict['Width'] = self.mapper.argDict['Width']-10;
+ self.xFor.argDict['ParamOp'] = self.xFor.argDict['ParamOp']-5;
+
+ return (sensorInputs, recursiveInputs)
diff --git a/behaviors/SynchTest.py b/behaviors/SynchTest.py
new file mode 100644
index 0000000..e7b8acc
--- /dev/null
+++ b/behaviors/SynchTest.py
@@ -0,0 +1,12 @@
+from operationscore.Behavior import *
+from pixelevents.SynchTestEvent import *
+import pdb
+class SynchTest(Behavior):
+ def behaviorInit(self):
+ self.rendered = False
+ def processResponse(self, sensorInputs, recurs):
+ if not self.rendered:
+ self.rendered = True
+ print 'here1'
+ return ([{'Location':'True', 'PixelEvent':SynchTestEvent({'Color':(255,0,0)})}], [])
+ return ([], [])
diff --git a/behaviors/TouchOSC.py b/behaviors/TouchOSC.py
index 1c41b5e..099d5e5 100644
--- a/behaviors/TouchOSC.py
+++ b/behaviors/TouchOSC.py
@@ -12,10 +12,11 @@ class TouchOSC(Behavior):
self.xy = (-1,-1)
def processResponse(self, sensorInputs, recursiveInputs):
ret = []
- for data in sensorInputs:
+ if sensorInputs:
+ data = sensorInputs[-1]#for data in sensorInputs:
if data['Path'] == '/1/fader1':
try:
- self.h = data['Value'][0]*360.0
+ self.h = data['Value'][0]
except:
pdb.set_trace()
elif data['Path'] == '/1/fader2':
diff --git a/behaviors/XYMove.py b/behaviors/XYMove.py
index 0ba3baf..11cee96 100644
--- a/behaviors/XYMove.py
+++ b/behaviors/XYMove.py
@@ -13,7 +13,6 @@ class XYMove(Behavior):
for loc in sensor:
oploc = dict(loc)
self.insertStepIfMissing(oploc)
- print oploc['YStep']
oploc['Location'] = Geo.addLocations((oploc['XStep'], oploc['YStep']), oploc['Location'])
ret.append(oploc)
return (ret, [])
diff --git a/config/6thFloor.xml b/config/6thFloor.xml
index 81f0c9f..ef195ec 100644
--- a/config/6thFloor.xml
+++ b/config/6thFloor.xml
@@ -186,7 +186,7 @@
<Behavior>
<Class>behaviors.BehaviorChain</Class>
<Args>
- <Id>inpexpanddim</Id>
+ <Id>doors</Id>
<Inputs>
<Id>pygamekey</Id>
</Inputs>
diff --git a/config/6thFloorOSC.xml b/config/6thFloorOSC.xml
index 792fd0c..cb1fd10 100644
--- a/config/6thFloorOSC.xml
+++ b/config/6thFloorOSC.xml
@@ -40,9 +40,17 @@
<InputElement>
<Class>inputs.OSCInput</Class>
<Args>
+ <Id>osc2</Id>
+ <Port>1234</Port>
+ <RefreshInterval>10</RefreshInterval>
+ </Args>
+ </InputElement>
+ <InputElement>
+ <Class>inputs.OSCInput</Class>
+ <Args>
<Id>osc</Id>
<Port>12345</Port>
- <RefreshInterval>10</RefreshInterval>
+ <RefreshInterval>20</RefreshInterval>
</Args>
</InputElement>
<InputElement>
@@ -52,14 +60,14 @@
<RefreshInterval>10</RefreshInterval>
</Args>
</InputElement>
- <!--<InputElement>
+ <InputElement>
<Class>inputs.TCPInput</Class>
<Args>
<Id>tcp</Id>
<Port>20120</Port>
<RefreshInterval>10</RefreshInterval>
</Args>
- </InputElement>-->
+ </InputElement>
<InputElement Id="followmouse">
<InheritsFrom>inputs/MouseFollower.xml</InheritsFrom>
</InputElement>
@@ -71,13 +79,64 @@
</InputElement>
</InputConfiguration>
<BehaviorConfiguration>
- <Behavior>
- <Class>behaviors.EchoBehavior</Class>
+ <Behavior>
+ <Class>behaviors.EchoBehavior</Class>
+ <Args>
+ <Id>echo</Id>
+ <z-index>0</z-index>
+ <RenderToScreen>False</RenderToScreen>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.BehaviorChain</Class>
+ <Args>
+ <Id>moveanddecay</Id>
+ <Inputs>
+ <Id>tcp</Id>
+ </Inputs>
+ <ChainedBehaviors>
+ <Id>move</Id>
+ <Id>decay</Id>
+ </ChainedBehaviors>
+ <RenderToScreen>True</RenderToScreen>
+ <Mapper>gaussmap</Mapper>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.MoveBehavior</Class>
+ <Args>
+ <Id>move</Id>
+ <XStep>3</XStep>
+ <YStep>3</YStep>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.MobileShakeBehavior</Class>
+ <Args>
+ <Id>mobileshake</Id>
+ <SizeMult>3</SizeMult>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.BehaviorChain</Class>
+ <Args>
+ <Id>shakeanddecay</Id>
+ <Inputs>
+ <Id>tcp</Id>
+ </Inputs>
+ <ChainedBehaviors>
+ <Id>mobileshake</Id>
+ <Id>slowdecay</Id>
+ </ChainedBehaviors>
+ <RenderToScreen>True</RenderToScreen>
+ <Mapper>simplemap</Mapper>
+ </Args>
+ </Behavior>
+ <Behavior>
<Args>
- <Id>echo</Id>
- <z-index>0</z-index>
- <RenderToScreen>False</RenderToScreen>
+ <Id>sixaxis</Id>
</Args>
+ <Class>behaviors.ControllerOSC</Class>
</Behavior>
<Behavior>
<Args>
@@ -265,10 +324,24 @@
<Behavior>
<Class>behaviors.BehaviorChain</Class>
<Args>
+ <Id>mousechaser2</Id>
+ <Inputs>
+ <Id>osc2</Id>
+ </Inputs>
+ <ChainedBehaviors>
+ <Id>sixaxis</Id>
+ <Id>singleframe</Id>
+ </ChainedBehaviors>
+ <RenderToScreen>True</RenderToScreen>
+ <Mapper>gaussmap</Mapper>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.BehaviorChain</Class>
+ <Args>
<Id>mousechaser</Id>
<Inputs>
<!--Id>followmouse</Id-->
- <Id>tcp</Id>
<Id>osc</Id>
</Inputs>
<ChainedBehaviors>
diff --git a/config/Demo.xml b/config/Demo.xml
new file mode 100644
index 0000000..525e468
--- /dev/null
+++ b/config/Demo.xml
@@ -0,0 +1,227 @@
+<!---All configuration items contain a "Class" tag specifying the python class they represent, and an "Args" tag specifying the args to be passed in.-->
+<LightInstallation>
+ <InstallationConfiguration>
+ <Defaults>
+ <PixelMapper>simplemap</PixelMapper>
+ </Defaults>
+ </InstallationConfiguration>
+ <PixelConfiguration>
+ <InheritsFrom>layouts/60StripLayout.xml</InheritsFrom>
+ </PixelConfiguration>
+ <PixelMapperConfiguration>
+ <PixelMapper>
+ <Class>pixelmappers.SimpleMapper</Class>
+ <Args>
+ <Id>simplemap</Id>
+ <CutoffDist>20</CutoffDist>
+ </Args>
+ </PixelMapper>
+ <PixelMapper>
+ <Class>pixelmappers.GaussianMapper</Class>
+ <Args>
+ <Id>gaussmap</Id>
+ <CutoffDist>30</CutoffDist>
+ <MinWeight>0.1</MinWeight>
+ <Width>10</Width>
+ <Height>1</Height>
+ </Args>
+ </PixelMapper>
+ </PixelMapperConfiguration>
+ <RendererConfiguration>
+ <Renderer>
+ <InheritsFrom>renderers/60StripSeq.xml</InheritsFrom>
+ </Renderer>
+ <Renderer>
+ <InheritsFrom>renderers/Pygame.xml</InheritsFrom>
+ </Renderer>
+ </RendererConfiguration>
+ <InputConfiguration>
+ <InputElement>
+ <Class>inputs.PygameInput</Class>
+ <Args>
+ <Id>pygameclick</Id>
+ <RefreshInterval>10</RefreshInterval>
+ <Clicks>True</Clicks>
+ </Args>
+ </InputElement>
+ <InputElement>
+ <Class>inputs.PygameInput</Class>
+ <Args>
+ <Id>pygamekey</Id>
+ <RefreshInterval>10</RefreshInterval>
+ <Keyboard>True</Keyboard>
+ </Args>
+ </InputElement>
+ <InputElement>
+ <Class>inputs.UDPInput</Class>
+ <Args>
+ <Id>udp</Id>
+ <Port>3344</Port>
+ <RefreshInterval>50</RefreshInterval>
+ </Args>
+ </InputElement>
+ <!--<InputElement>
+ <Class>inputs.TCPInput</Class>
+ <Args>
+ <Id>tcp</Id>
+ <Port>20120</Port>
+ <RefreshInterval>10</RefreshInterval>
+ </Args>
+ </InputElement>-->
+ <InputElement Id="followmouse">
+ <InheritsFrom>inputs/MouseFollower.xml</InheritsFrom>
+ </InputElement>
+ </InputConfiguration>
+ <BehaviorConfiguration>
+ <Behavior Id="colorchange">
+ <InheritsFrom>behaviors/RandomColor.xml</InheritsFrom>
+ <Args>
+ <ColorList>
+ <Val>(255,0,0)</Val>
+ <Val>(0,0,255)</Val>
+ </ColorList>
+ </Args>
+ </Behavior>
+ <Behavior Id="decay">
+ <InheritsFrom>behaviors/PixelDecay.xml</InheritsFrom>
+ </Behavior>
+ <Behavior Id="singleframe">
+ <InheritsFrom>behaviors/SingleFrame.xml</InheritsFrom>
+ </Behavior>
+ <Behavior Id="slowdecay">
+ <InheritsFrom>behaviors/PixelDecay.xml</InheritsFrom>
+ <Args>
+ <Coefficient>.01</Coefficient>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.XYMove</Class>
+ <Args>
+ <Id>xymove</Id>
+ <XStep>5</XStep>
+ <YStep>2</YStep>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.RestrictLocation</Class>
+ <Args>
+ <Id>xbounce</Id>
+ <Action>{val}*-1</Action>
+ <ParamName>XStep</ParamName>
+ <LocationRestriction>{x}&lt;0 or {x}&gt;800</LocationRestriction>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.RestrictLocation</Class>
+ <Args>
+ <Id>ybounce</Id>
+ <Action>{val}*-1</Action>
+ <ParamName>YStep</ParamName>
+ <LocationRestriction>{y}&lt;0 or {y}&gt;200</LocationRestriction>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.BehaviorChain</Class>
+ <Args>
+ <Id>movebounce</Id>
+ <ChainedBehaviors>
+ <Id>xymove</Id>
+ <Id>ybounce</Id>
+ <Id>xbounce</Id>
+ </ChainedBehaviors>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.ModifyParam</Class>
+ <Args>
+ <Id>ysin</Id>
+ <ParamName>YStep</ParamName>
+ <ParamType>Sensor</ParamType>
+ <ParamOp>4*math.sin({x}/float(40))</ParamOp>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.DebugBehavior</Class>
+ <Args>
+ <Id>debug</Id>
+ <z-index>0</z-index>
+ <Inputs>
+ <Id>pygamekey</Id>
+ <Id>udp</Id>
+ </Inputs>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.Square</Class>
+ <Args>
+ <Id>square</Id>
+ <Width>20</Width>
+ </Args>
+ </Behavior>
+ <Behavior Id="recursivedecay">
+ <InheritsFrom>behaviors/LoopAndDie.xml</InheritsFrom>
+ <Args>
+ <InitialResponseCount>80</InitialResponseCount>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.BehaviorChain</Class>
+ <Args>
+ <Id>runcolordecay</Id>
+ <Inputs>
+ <Id>pygameclick</Id>
+ </Inputs>
+ <ChainedBehaviors>
+ <Id>colorchange</Id>
+ <Id>mover</Id>
+ <Id>decay</Id>
+ </ChainedBehaviors>
+ <RecursiveHooks>{'mover':'movebounce'}</RecursiveHooks>
+ <RenderToScreen>True</RenderToScreen>
+ <Mapper>gaussmap</Mapper>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.ResponseMover</Class>
+ <Args>
+ <Id>mover</Id>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.RandomWalk</Class>
+ <Args>
+ <Id>randmovement</Id>
+ <StepSize>2</StepSize>
+ </Args>
+ </Behavior>
+ <Behavior Id="accelerate">
+ <InheritsFrom>behaviors/Accelerate.xml</InheritsFrom>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.EchoBehavior</Class>
+ <Args>
+ <Id>echo</Id>
+ <z-index>0</z-index>
+ <RenderToScreen>False</RenderToScreen>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.BehaviorChain</Class>
+ <Args>
+ <Id>mousechaser</Id>
+ <Inputs>
+ <Id>followmouse</Id>
+ </Inputs>
+ <ChainedBehaviors>
+ <Id>echo</Id>
+ <Id>square</Id>
+ <Id>singleframe</Id>
+ </ChainedBehaviors>
+ <RenderToScreen>True</RenderToScreen>
+ </Args>
+ </Behavior>
+ <Behavior Id="running">
+ <InheritsFrom>behaviors/RunningBehavior.xml</InheritsFrom>
+ </Behavior>
+ </BehaviorConfiguration>
+</LightInstallation>
diff --git a/config/FireflyDemo.xml b/config/FireflyDemo.xml
new file mode 100644
index 0000000..856569e
--- /dev/null
+++ b/config/FireflyDemo.xml
@@ -0,0 +1,163 @@
+<!-- Demo of the flasher behavior. -->
+<!-- Bubbles or fireflies move around and fade on and off -->
+<!-- Jim Salem 1/28/11 jsalem@gmail.com -->
+<!-- Movement is pretty wonky. -->
+
+<!---All configuration items contain a "Class" tag specifying the python class they represent, and an "Args" tag specifying the args to be passed in.-->
+<LightInstallation>
+ <InstallationConfiguration>
+ <Defaults>
+ <PixelMapper>simplemap</PixelMapper>
+ </Defaults>
+ </InstallationConfiguration>
+ <PixelConfiguration>
+ <InheritsFrom>layouts/60StripLayout.xml</InheritsFrom>
+ </PixelConfiguration>
+ <PixelMapperConfiguration>
+ <PixelMapper>
+ <Class>pixelmappers.SimpleMapper</Class>
+ <Args>
+ <Id>simplemap</Id>
+ <CutoffDist>20</CutoffDist>
+ </Args>
+ </PixelMapper>
+ <PixelMapper>
+ <Class>pixelmappers.GaussianMapper</Class>
+ <Args>
+ <Id>gaussmap</Id>
+ <CutoffDist>30</CutoffDist>
+ <MinWeight>0.1</MinWeight>
+ <Width>10</Width>
+ <Height>1</Height>
+ </Args>
+ </PixelMapper>
+ </PixelMapperConfiguration>
+ <RendererConfiguration>
+ <Renderer>
+ <InheritsFrom>renderers/60StripSeq.xml</InheritsFrom>
+ </Renderer>
+ <Renderer>
+ <InheritsFrom>renderers/Pygame.xml</InheritsFrom>
+ </Renderer>
+ </RendererConfiguration>
+ <InputConfiguration>
+ <InputElement>
+ <Class>inputs.PygameInput</Class>
+ <Args>
+ <Id>pygameclick</Id>
+ <RefreshInterval>10</RefreshInterval>
+ <Clicks>True</Clicks>
+ </Args>
+ </InputElement>
+ <InputElement>
+ <Class>inputs.PygameInput</Class>
+ <Args>
+ <Id>pygamekey</Id>
+ <RefreshInterval>10</RefreshInterval>
+ <Keyboard>True</Keyboard>
+ </Args>
+ </InputElement>
+ <InputElement>
+ <Class>inputs.UDPInput</Class>
+ <Args>
+ <Id>udp</Id>
+ <Port>3344</Port>
+ <RefreshInterval>50</RefreshInterval>
+ </Args>
+ </InputElement>
+ </InputConfiguration>
+
+ <BehaviorConfiguration>
+ <Behavior>
+ <Class>behaviors.RandomSetBrightColorBehavior</Class>
+ <Args>
+ <Id>setbrightcolor</Id>
+ </Args>
+ </Behavior>
+ <Behavior Id="decay">
+ <InheritsFrom>behaviors/PixelDecay.xml</InheritsFrom>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.RestrictLocation</Class>
+ <Args>
+ <Id>xbounce</Id>
+ <Action>{val}*-1</Action>
+ <ParamName>XStep</ParamName>
+ <LocationRestriction>{x}&lt;0 or {x}&gt;800</LocationRestriction>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.RestrictLocation</Class>
+ <Args>
+ <Id>ybounce</Id>
+ <Action>{val}*-1</Action>
+ <ParamName>YStep</ParamName>
+ <LocationRestriction>{y}&lt;0 or {y}&gt;200</LocationRestriction>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.Flasher</Class>
+ <Args>
+ <Id>flasher</Id>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.BehaviorChain</Class>
+ <Args>
+ <Id>flashermovebounce</Id>
+ <ChainedBehaviors>
+ <Id>randmovement</Id>
+ <Id>ybounce</Id>
+ <Id>xbounce</Id>
+ <Id>flasher</Id>
+ </ChainedBehaviors>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.Square</Class>
+ <Args>
+ <Id>square</Id>
+ <Width>15</Width>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.RandomWalk</Class>
+ <Args>
+ <Id>randmovement</Id>
+ <StepSize>20</StepSize>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.BehaviorChain</Class>
+ <Args>
+ <Id>runcolordecay</Id>
+ <Inputs>
+ <Id>pygameclick</Id>
+ </Inputs>
+ <ChainedBehaviors>
+ <Id>setbrightcolor</Id>
+ <Id>mover</Id>
+ <Id>decay</Id>
+ </ChainedBehaviors>
+ <RecursiveHooks>{'mover':'flashermovebounce'}</RecursiveHooks>
+ <RenderToScreen>True</RenderToScreen>
+ <Mapper>gaussmap</Mapper>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.ResponseMover</Class>
+ <Args>
+ <Id>mover</Id>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.EchoBehavior</Class>
+ <Args>
+ <Id>echo</Id>
+ <z-index>0</z-index>
+ <Color>(90,90,90)</Color>
+ <RenderToScreen>False</RenderToScreen>
+ </Args>
+ </Behavior>
+ </BehaviorConfiguration>
+</LightInstallation>
diff --git a/config/HTMLTest.xml b/config/HTMLTest.xml
new file mode 100755
index 0000000..159cec4
--- /dev/null
+++ b/config/HTMLTest.xml
@@ -0,0 +1,58 @@
+<LightInstallation>
+ <InstallationConfiguration>
+ <Defaults>
+ <PixelMapper>simplemap</PixelMapper>
+ </Defaults>
+ </InstallationConfiguration>
+ <PixelConfiguration>
+ <InheritsFrom>layouts/BasicSixStrip.xml</InheritsFrom>
+ </PixelConfiguration>
+ <PixelMapperConfiguration>
+ <PixelMapper>
+ <Class>pixelmappers.SimpleMapper</Class>
+ <Args>
+ <Id>simplemap</Id>
+ <CutoffDist>20</CutoffDist>
+ </Args>
+ </PixelMapper>
+ <PixelMapper>
+ <Class>pixelmappers.GaussianMapper</Class>
+ <Args>
+ <Id>gaussmap</Id>
+ <CutoffDist>30</CutoffDist>
+ <MinWeight>0.1</MinWeight>
+ <Width>10</Width>
+ <Height>1</Height>
+ </Args>
+ </PixelMapper>
+ </PixelMapperConfiguration>
+ <RendererConfiguration>
+ <Renderer>
+ <InheritsFrom>renderers/Pygame.xml</InheritsFrom>
+ </Renderer>
+ </RendererConfiguration>
+ <InputConfiguration>
+ <InputElement>
+ <Class>inputs.HTMLInput</Class>
+ <Args>
+ <Id>weatherinput</Id>
+ <Src>'http://sailing.mit.edu/weather/'</Src>
+ <!--<Regex>'rtWindSpeed = (\d+).*rtWindDir = (\d+)'</Regex>-->
+ <Regex>'rtWindSpeed = (\d+).*\s.*\s.*rtWindDir = (\d+)'</Regex>
+ <!--<RefreshInterval>60000</RefreshInterval>-->
+ </Args>
+ </InputElement>
+ </InputConfiguration>
+ <BehaviorConfiguration>
+ <Behavior>
+ <Class>behaviors.EchoBehavior</Class>
+ <Args>
+ <Inputs>
+ <Id>weatherinput</Id>
+ </Inputs>
+ <Id>echo</Id>
+ <RenderToScreen>False</RenderToScreen>
+ </Args>
+ </Behavior>
+ </BehaviorConfiguration>
+</LightInstallation>
diff --git a/config/Jennifer.xml b/config/Jennifer.xml
new file mode 100644
index 0000000..179c462
--- /dev/null
+++ b/config/Jennifer.xml
@@ -0,0 +1,129 @@
+<!---All configuration items contain a "Class" tag specifying the python class they represent, and an "Args" tag specifying the args to be passed in.-->
+<LightInstallation>
+ <InstallationConfiguration>
+ <Defaults>
+ <PixelMapper>simplemap</PixelMapper>
+ </Defaults>
+ </InstallationConfiguration>
+ <PixelConfiguration>
+ <InheritsFrom>layouts/60StripLayout.xml</InheritsFrom>
+ </PixelConfiguration>
+ <PixelMapperConfiguration>
+ <PixelMapper>
+ <Class>pixelmappers.SimpleMapper</Class>
+ <Args>
+ <Id>simplemap</Id>
+ <CutoffDist>20</CutoffDist>
+ </Args>
+ </PixelMapper>
+ </PixelMapperConfiguration>
+ <RendererConfiguration>
+ <Renderer>
+ <InheritsFrom>renderers/60StripSeq.xml</InheritsFrom>
+ </Renderer>
+ <Renderer>
+ <InheritsFrom>renderers/Pygame.xml</InheritsFrom>
+ </Renderer>
+ </RendererConfiguration>
+ <InputConfiguration>
+ <InputElement>
+ <Class>inputs.PygameInput</Class>
+ <Args><!--Passed as a dictionary-->
+ <Id>pygameclick</Id>
+ <RefreshInterval>10</RefreshInterval>
+ <Clicks>True</Clicks>
+ </Args>
+ </InputElement>
+ <InputElement>
+ <Class>inputs.PygameInput</Class>
+ <Args><!--Passed as a dictionary-->
+ <Id>pygamekey</Id>
+ <RefreshInterval>10</RefreshInterval>
+ <Keyboard>True</Keyboard>
+ </Args>
+ </InputElement>
+ <InputElement>
+ <Class>inputs.UDPInput</Class>
+ <Args>
+ <Id>udp</Id>
+ <Port>3344</Port>
+ <RefreshInterval>50</RefreshInterval>
+ </Args>
+ </InputElement>
+ </InputConfiguration>
+ <BehaviorConfiguration>
+ <Behavior Id="dim">
+ <InheritsFrom>behaviors/DimColor.xml</InheritsFrom>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.Expand</Class>
+ <Args>
+ <Id>expand</Id>
+ <ExpandRate>8</ExpandRate>
+ </Args>
+ </Behavior>
+ <Behavior Id="colorchange">
+ <InheritsFrom>behaviors/RandomColor.xml</InheritsFrom>
+ <Args>
+ <ColorList>
+ <Val>(255,0,0)</Val>
+ <Val>(0,0,255)</Val>
+ </ColorList>
+ </Args>
+ </Behavior>
+ <Behavior Id="decay">
+ <InheritsFrom>behaviors/PixelDecay.xml</InheritsFrom>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.BehaviorChain</Class>
+ <Args>
+ <Id>expanddie</Id>
+ <ChainedBehaviors>
+ <Id>expand</Id>
+ <Id>decexpand</Id>
+ <Id>dim</Id>
+ <Id>8sectimeout</Id>
+ </ChainedBehaviors>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.ExpandingColorZones</Class>
+ <Args>
+ <Id>colorzones</Id>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.BehaviorChain</Class>
+ <Args>
+ <Id>colorbars</Id>
+ <Inputs>
+ <Id>pygamekey</Id>
+ <Id>udp</Id>
+ </Inputs>
+ <ChainedBehaviors>
+ <Id>colorzones</Id>
+ <Id>mover</Id>
+ <Id>decay</Id>
+ </ChainedBehaviors>
+ <RecursiveHooks>{'mover':'expanddie'}</RecursiveHooks>
+ <RenderToScreen>True</RenderToScreen>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.Timeout</Class>
+ <Args>
+ <Id>8sectimeout</Id>
+ <Timeout>8000</Timeout>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.ResponseMover</Class>
+ <Args>
+ <Id>mover</Id>
+ </Args>
+ </Behavior>
+ <Behavior Id="decexpand" ParamName="ExpandRate">
+ <InheritsFrom>behaviors/Deccelerate.xml</InheritsFrom>
+ </Behavior>
+ </BehaviorConfiguration>
+</LightInstallation>
diff --git a/config/Kuan.xml b/config/Kuan.xml
new file mode 100644
index 0000000..7d76ed4
--- /dev/null
+++ b/config/Kuan.xml
@@ -0,0 +1,108 @@
+<LightInstallation>
+ <InstallationConfiguration>
+ <Defaults>
+ <PixelMapper>simplemap</PixelMapper>
+ </Defaults>
+ </InstallationConfiguration>
+ <PixelConfiguration>
+ <InheritsFrom>layouts/60StripLayout.xml</InheritsFrom>
+ </PixelConfiguration>
+ <PixelMapperConfiguration>
+ <PixelMapper>
+ <Class>pixelmappers.SimpleMapper</Class>
+ <Args>
+ <Id>simplemap</Id>
+ <CutoffDist>20</CutoffDist>
+ </Args>
+ </PixelMapper>
+ </PixelMapperConfiguration>
+ <RendererConfiguration>
+ <Renderer>
+ <InheritsFrom>renderers/60StripSeq.xml</InheritsFrom>
+ </Renderer>
+ <Renderer>
+ <InheritsFrom>renderers/Pygame.xml</InheritsFrom>
+ </Renderer>
+ </RendererConfiguration>
+ <InputConfiguration>
+ <InputElement>
+ <Class>inputs.PygameInput</Class>
+ <Args>
+ <Id>pygamekey</Id>
+ <RefreshInterval>10</RefreshInterval>
+ <Keyboard>True</Keyboard>
+ </Args>
+ </InputElement>
+ </InputConfiguration>
+ <BehaviorConfiguration>
+ <Behavior Id="risefall" MaxHeight="200">
+ <InheritsFrom>behaviors/RiseFall.xml</InheritsFrom>
+ </Behavior>
+ <Behavior Id="dim">
+ <InheritsFrom>behaviors/DimColor.xml</InheritsFrom>
+ </Behavior>
+ <Behavior Id="colorchange">
+ <InheritsFrom>behaviors/RandomColor.xml</InheritsFrom>
+ </Behavior>
+ <Behavior Id="decay">
+ <InheritsFrom>behaviors/PixelDecay.xml</InheritsFrom>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.BehaviorChain</Class>
+ <Args>
+ <Id>risefalldie</Id>
+ <ChainedBehaviors>
+ <Id>risefall</Id>
+ <Id>2sec</Id>
+ <Id>dim</Id>
+ </ChainedBehaviors>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.BehaviorChain</Class>
+ <Args>
+ <Id>doors</Id>
+ <Inputs>
+ <Id>pygamekey</Id>
+ </Inputs>
+ <ChainedBehaviors>
+ <Id>mitdoors</Id>
+ <Id>colorchange</Id>
+ <Id>mover</Id>
+ <Id>decay</Id>
+ </ChainedBehaviors>
+ <RecursiveHooks>{'mover':'risefalldie'}</RecursiveHooks>
+ <RenderToScreen>True</RenderToScreen>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.Timeout</Class>
+ <Args>
+ <Id>2sec</Id>
+ <Timeout>2000</Timeout>
+ </Args>
+ </Behavior>
+ <!--Behavior>
+ <Class>behaviors.ModifyParam</Class>
+ <Args>
+ <Id>swaposc</Id>
+ <ParamType>Sensor</ParamType>
+ <ParamName>Oscillate</ParamName>
+ <ParamOp>not {val}</ParamOp>
+ </Args>
+ </Behavior-->
+ <Behavior>
+ <Class>behaviors.MITDoors</Class>
+ <Args>
+ <Id>mitdoors</Id>
+ <Bottom>200</Bottom>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.ResponseMover</Class>
+ <Args>
+ <Id>mover</Id>
+ </Args>
+ </Behavior>
+ </BehaviorConfiguration>
+</LightInstallation>
diff --git a/config/MobileTest.xml b/config/MobileTest.xml
index af94c25..63c3b47 100644
--- a/config/MobileTest.xml
+++ b/config/MobileTest.xml
@@ -26,6 +26,16 @@
<Height>1</Height>
</Args>
</PixelMapper>
+ <PixelMapper>
+ <Class>pixelmappers.GaussianMapper</Class>
+ <Args>
+ <Id>mobilegaussmap</Id>
+ <CutoffDist>30</CutoffDist>
+ <MinWeight>0.1</MinWeight>
+ <Width>10</Width>
+ <Height>1</Height>
+ </Args>
+ </PixelMapper>
</PixelMapperConfiguration>
<RendererConfiguration>
<Renderer>
@@ -227,26 +237,12 @@
</Inputs>
<ChainedBehaviors>
<Id>move</Id>
+ <Id>mobileshake</Id>
<Id>decay</Id>
</ChainedBehaviors>
<RenderToScreen>True</RenderToScreen>
- <Mapper>gaussmap</Mapper>
+ <Mapper>mobilegaussmap</Mapper>
</Args>
</Behavior>
- <Behavior>
- <Class>behaviors.BehaviorChain</Class>
- <Args>
- <Id>shakeanddecay</Id>
- <Inputs>
- <Id>tcp</Id>
- </Inputs>
- <ChainedBehaviors>
- <Id>mobileshake</Id>
- <Id>slowdecay</Id>
- </ChainedBehaviors>
- <RenderToScreen>True</RenderToScreen>
- <Mapper>simplemap</Mapper>
- </Args>
- </Behavior>
</BehaviorConfiguration>
</LightInstallation>
diff --git a/config/SmootWindTest.xml b/config/SmootWindTest.xml
new file mode 100755
index 0000000..f6e7a97
--- /dev/null
+++ b/config/SmootWindTest.xml
@@ -0,0 +1,181 @@
+<!---All configuration items contain a "Class" tag specifying the python class they represent, and an "Args" tag specifying the args to be passed in.-->
+<LightInstallation>
+ <InstallationConfiguration>
+ <Defaults>
+ <PixelMapper>simplemap</PixelMapper>
+ </Defaults>
+ </InstallationConfiguration>
+ <PixelConfiguration>
+ <InheritsFrom>layouts/60StripLayout.xml</InheritsFrom>
+ </PixelConfiguration>
+ <PixelMapperConfiguration>
+ <PixelMapper>
+ <Class>pixelmappers.SimpleMapper</Class>
+ <Args>
+ <Id>simplemap</Id>
+ <CutoffDist>20</CutoffDist>
+ </Args>
+ </PixelMapper>
+ <PixelMapper>
+ <Class>pixelmappers.GaussianMapper</Class>
+ <Args>
+ <Id>gaussmap</Id>
+ <CutoffDist>10</CutoffDist>
+ <MinWeight>0.1</MinWeight>
+ <Width>10</Width>
+ <Height>5</Height>
+ </Args>
+ </PixelMapper>
+ <PixelMapper>
+ <Class>pixelmappers.WindGaussianMapper</Class>
+ <Args>
+ <Id>windgaussmap</Id>
+ <CutoffDist>150</CutoffDist>
+ <MinWeight>0.005</MinWeight>
+ <Width>30</Width>
+ <Height>10</Height>
+ </Args>
+ </PixelMapper>
+ </PixelMapperConfiguration>
+ <RendererConfiguration>
+ <Renderer>
+ <InheritsFrom>renderers/60StripSeq.xml</InheritsFrom>
+ </Renderer>
+ <Renderer>
+ <InheritsFrom>renderers/Pygame.xml</InheritsFrom>
+ </Renderer>
+ </RendererConfiguration>
+ <InputConfiguration>
+ <InputElement>
+ <Class>inputs.PygameInput</Class>
+ <Args><!--Passed as a dictionary-->
+ <Id>pygame</Id>
+ <RefreshInterval>1</RefreshInterval>
+ </Args>
+ </InputElement>
+ <InputElement>
+ <Class>inputs.PygameInput</Class>
+ <Args>
+ <Id>pygamekey</Id>
+ <RefreshInterval>10</RefreshInterval>
+ <Keyboard>True</Keyboard>
+ </Args>
+ </InputElement>
+ <InputElement>
+ <Class>inputs.HTMLInput</Class>
+ <Args>
+ <Id>weatherinput</Id>
+ <Src>'http://sailing.mit.edu/weather/'</Src>
+ <!--<Regex>'rtWindSpeed = (\d+).*rtWindDir = (\d+)'</Regex>-->
+ <Regex>'rtWindSpeed = (\d+).*\s.*\s.*rtWindDir = (\d+)'</Regex>
+ <!--<RefreshInterval>60000</RefreshInterval>-->
+ </Args>
+ </InputElement>
+ <InputElement>
+ <Class>inputs.RandomLocs</Class>
+ <Args>
+ <Id>randomLoc</Id>
+ </Args>
+ </InputElement>
+ </InputConfiguration>
+ <BehaviorConfiguration>
+ <Behavior Id="colorchange">
+ <InheritsFrom>behaviors/RandomColor.xml</InheritsFrom>
+ </Behavior>
+ <Behavior Id="staticcolor">
+ <InheritsFrom>behaviors/RandomColor.xml</InheritsFrom>
+ <Args>
+ <ColorList>
+ <Val>(100,200,255)</Val>
+ <Val>(50,200,255)</Val>
+ <Val>(0,200,255)</Val>
+ <Val>(0,150,255)</Val>
+ </ColorList>
+ </Args>
+ </Behavior>
+ <Behavior Id="decay">
+ <InheritsFrom>behaviors/PixelDecay.xml</InheritsFrom>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.XYMove</Class>
+ <Args>
+ <Id>xymove</Id>
+ <XStep>0</XStep>
+ <YStep>0</YStep>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.BehaviorChain</Class>
+ <Args>
+ <Id>movebounce</Id>
+ <ChainedBehaviors>
+ <Id>xymove</Id>
+ <Id>yfor</Id>
+ <Id>xfor</Id>
+ <Id>20sectimeout</Id>
+ </ChainedBehaviors>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.Timeout</Class>
+ <Args>
+ <Id>20sectimeout</Id>
+ <Timeout>20000</Timeout>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.ModifyParam</Class>
+ <Args>
+ <Id>yfor</Id>
+ <ParamName>YStep</ParamName>
+ <ParamType>Sensor</ParamType>
+ <ParamOp>2*(2*math.sin({x}/float(100))+math.sin({x}/float(50)))</ParamOp>
+ </Args>
+ </Behavior>
+
+ <Behavior>
+ <Class>behaviors.ModifyParam</Class>
+ <Args>
+ <Id>xfor</Id>
+ <ParamName>XStep</ParamName>
+ <ParamType>Sensor</ParamType>
+ <!--<ParamOp>75</ParamOp>-->
+ <ParamOp>25</ParamOp>
+ </Args>
+ </Behavior>
+
+ <Behavior>
+ <Class>behaviors.SmootWind</Class>
+ <Args>
+ <Id>smootwind</Id>
+ <Inputs>
+ <Id>pygamekey</Id>
+ </Inputs>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.ResponseMover</Class>
+ <Args>
+ <Id>mover</Id>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.BehaviorChain</Class>
+ <Args>
+ <Id>xymover</Id>
+ <Inputs>
+ <Id>pygame</Id>
+ <Id>randomLoc</Id>
+ </Inputs>
+ <ChainedBehaviors>
+ <Id>staticcolor</Id>
+ <Id>mover</Id>
+ <Id>decay</Id>
+ </ChainedBehaviors>
+ <RecursiveHooks>{'mover':'movebounce'}</RecursiveHooks>
+ <RenderToScreen>True</RenderToScreen>
+ <Mapper>windgaussmap</Mapper>
+ </Args>
+ </Behavior>
+ </BehaviorConfiguration>
+</LightInstallation>
diff --git a/config/SynchTest.xml b/config/SynchTest.xml
new file mode 100644
index 0000000..fcb8293
--- /dev/null
+++ b/config/SynchTest.xml
@@ -0,0 +1,39 @@
+<!---All configuration items contain a "Class" tag specifying the python class they represent, and an "Args" tag specifying the args to be passed in.-->
+<LightInstallation>
+ <InstallationConfiguration>
+ <Defaults>
+ <PixelMapper>simplemap</PixelMapper>
+ </Defaults>
+ </InstallationConfiguration>
+ <PixelConfiguration>
+ <InheritsFrom>layouts/60StripLayout.xml</InheritsFrom>
+ </PixelConfiguration>
+ <PixelMapperConfiguration>
+ <PixelMapper>
+ <Class>pixelmappers.SimpleMapper</Class>
+ <Args>
+ <Id>simplemap</Id>
+ <CutoffDist>20</CutoffDist>
+ </Args>
+ </PixelMapper>
+ </PixelMapperConfiguration>
+ <RendererConfiguration>
+ <Renderer>
+ <InheritsFrom>renderers/60StripSeq.xml</InheritsFrom>
+ </Renderer>
+ <Renderer>
+ <InheritsFrom>renderers/Pygame.xml</InheritsFrom>
+ </Renderer>
+ </RendererConfiguration>
+ <InputConfiguration>
+ </InputConfiguration>
+ <BehaviorConfiguration>
+ <Behavior>
+ <Class>behaviors.SynchTest</Class>
+ <Args>
+ <Id>synch</Id>
+ <RenderToScreen>True</RenderToScreen>
+ </Args>
+ </Behavior>
+ </BehaviorConfiguration>
+</LightInstallation>
diff --git a/inputs/HTMLInput.py b/inputs/HTMLInput.py
new file mode 100755
index 0000000..9697a32
--- /dev/null
+++ b/inputs/HTMLInput.py
@@ -0,0 +1,29 @@
+from operationscore.Input import *
+import urllib, re
+
+"""
+HTML Input, which takes 2 arguments:
+- 'Src': a URL to a web page, and
+- 'Regex': a Regex to parse data out of the web page.
+The input parses the source code of the web page according to the regex, and processes the parsed regex groups.
+"""
+class HTMLInput(Input):
+ def inputInit(self):
+ self.src = self.argDict['Src']
+ self.regex = self.argDict['Regex']
+
+ def getHTML(self):
+ self.sock = urllib.urlopen(self.src);
+ self.html = self.sock.read()
+ self.sock.close()
+
+ def sensingLoop(self):
+ self.getHTML()
+ self.dataList = []
+
+ pattern = re.compile(self.regex)
+ matchObj = pattern.search(self.html)
+ self.dataList = matchObj.groups()
+
+ self.respond(self.dataList)
+
diff --git a/inputs/OSCInput.py b/inputs/OSCInput.py
index f867fb5..ba1e035 100644
--- a/inputs/OSCInput.py
+++ b/inputs/OSCInput.py
@@ -7,8 +7,8 @@ class OSCInput(Input):
def inputInit(self):
HOST = '' # Symbolic name meaning all available interfaces
PORT = self['Port'] # Arbitrary non-privileged port
- self.server = liblo.Server(PORT)
- self.server.add_method(None,None, self.fallback)
+ self.server = liblo.Server(PORT)
+ self.server.add_method(None,None, self.fallback)
# except liblo.ServerError, err:
# main_log.error(str(err))
diff --git a/inputs/PygameInput.py b/inputs/PygameInput.py
index 399a77e..480630c 100644
--- a/inputs/PygameInput.py
+++ b/inputs/PygameInput.py
@@ -23,10 +23,15 @@ class PygameInput(Input):
if event.key == 27:
self.die()
if self['Keyboard']:
- self.respond({'Key': event.key})
+ try:
+ self.respond({'Key': event.key, 'KeyChar': chr(event.key)})
+ except:
+ self.respond({'Key': event.key})
return
else:
pygame.event.post(event)
if event.type is MOUSEBUTTONDOWN:
if self['Clicks']:
self.respond({Strings.LOCATION: pygame.mouse.get_pos()})
+ else:
+ pygame.event.post(event)
diff --git a/inputs/RandomLocs.py b/inputs/RandomLocs.py
index 2719981..f4182cf 100644
--- a/inputs/RandomLocs.py
+++ b/inputs/RandomLocs.py
@@ -1,16 +1,16 @@
-import util.TimeOps as clock
-import random
-import util.Geo as Geo
-import util.Strings as Strings
-from operationscore.Input import *
-class RandomLocs(Input):
- """RandomLocs is an Input that generates RandomLocations at a preset time interval. Just a
- prototype, some assembly required."""
-
- def inputInit(self):
- self['LastEvent'] = clock.time()
- def sensingLoop(self): #TODO: move to params
- currentTime = clock.time()
- if currentTime - self['LastEvent'] > 2000:
- self.respond({Strings.LOCATION: Geo.randomLoc((50,50))})
- self['LastEvent'] = currentTime
+import util.TimeOps as clock
+import random
+import util.Geo as Geo
+import util.Strings as Strings
+from operationscore.Input import *
+class RandomLocs(Input):
+ """RandomLocs is an Input that generates RandomLocations at a preset but randomly changing time interval. Just a
+ prototype, some assembly required."""
+
+ def inputInit(self):
+ self['LastEvent'] = clock.time()
+ def sensingLoop(self): #TODO: move to params
+ currentTime = clock.time()
+ if currentTime - self['LastEvent'] > 200+500*random.random():
+ self.respond({Strings.LOCATION: Geo.randomLoc((200,200))})
+ self['LastEvent'] = currentTime
diff --git a/inputs/TCPInput.py b/inputs/TCPInput.py
index 17ea7e6..e565649 100644
--- a/inputs/TCPInput.py
+++ b/inputs/TCPInput.py
@@ -4,6 +4,7 @@ from operationscore.Input import *
import socket, json, time
import logging as main_log
import string
+from select import select
class TCPInput(Input):
"""TCPInput is a input to receive input on a TCP port. In its current incarnation, it parses
@@ -20,9 +21,20 @@ class TCPInput(Input):
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.sock.bind((self.HOST, self.PORT))
self.sock.listen(1)
- (self.conn, self.address) = self.sock.accept()
+
+ isreadable=select([self.sock],[],[], 0)[0]
+ self.conn = None
+ if isreadable:
+ (self.conn, self.address) = self.sock.accept()
def sensingLoop(self):
+ if self.conn == None:
+ isreadable=select([self.sock],[],[], 0)[0]
+ if isreadable:
+ (self.conn, self.address) = self.sock.accept()
+ else:
+ return
+
data = self.conn.recv(self.BUFFER_SIZE)
main_log.debug('Incoming data', data)
@@ -38,6 +50,8 @@ class TCPInput(Input):
for datagroup in data.split('\n'):
if datagroup != None and datagroup != '':
dataDict = json.loads(datagroup)
+ #if dataDict['type'] != 1:
+ #print dataDict
self.respond(dataDict)
except Exception as exp:
print str(exp)
diff --git a/pixelcore/Pixel.py b/pixelcore/Pixel.py
index 6ff2e67..4e7cfce 100644
--- a/pixelcore/Pixel.py
+++ b/pixelcore/Pixel.py
@@ -1,4 +1,5 @@
import util.ColorOps as color
+from logger import main_log
import pdb
from pixelevents.StepEvent import *
import util.TimeOps as timeops
@@ -57,7 +58,8 @@ class Pixel:
if eventResult != None:
scaledEvent = color.multiplyColor(eventResult,scale)
if (scaledEvent[0] + scaledEvent[1] + scaledEvent[2]) < 5:
- deadEvents.append(eventObj)
+ pass
+ #deadEvents.append(eventObj)
else:
colors.append(scaledEvent)
else:
diff --git a/pixelcore/Screen.py b/pixelcore/Screen.py
index 9a81df7..ada8d4a 100644
--- a/pixelcore/Screen.py
+++ b/pixelcore/Screen.py
@@ -22,14 +22,14 @@ class Screen:
sizeValid = False
self.pixelsSorted = False
- def addStrip(self, lS):
- self.pixelStrips.append(lS)
+ def addStrip(self, strip):
+ self.pixelStrips.append(strip)
self.sizeValid = False #keep track of whether or not our screen size has
self.pixelsSorted = False
#been invalidated by adding more pixels
def pixelsInRange(self, minX, maxX):
- """Returns (pixelIndex, pixel). Does a binary search."""
+ """Returns (pixelIndex, pixel). Does a binary search. Sorts first if neccesary."""
if not self.pixelsSorted:
self.computeXSortedPixels()
minIndex = Search.find_ge(self.xPixelLocs, minX)
@@ -48,12 +48,11 @@ class Screen:
return itertools.chain(*[strip.__iter__() for strip in \
self.pixelStrips]) #the * operator breaks the list into args
- #increment time -- This processes all queued responses. Responses generated
- #during this period are added to the queue that will be processed on the next
- #time step.
#SUBVERTING DESIGN FOR EFFICIENCY 1/24/11, RCOH -- It would be cleaner to store the time on the responses
#themselves, however, it is faster to just pass it in.
def timeStep(self, currentTime=None):
+ """Increments time -- This processes all queued responses, adding that to a queue that will
+ be processed on the next time step."""
if currentTime == None:
currentTime = timeops.time()
tempQueue = list(self.responseQueue)
@@ -66,6 +65,7 @@ class Screen:
self.responseQueue.append(responseInfo)
def getSize(self):
+ """Returns the size of the screen in the form: (minx, miny, maxx, maxy)"""
if self.sizeValid:
return self.size
(minX, minY, maxX, maxY) = (sys.maxint,sys.maxint,-sys.maxint,-sys.maxint)
@@ -79,24 +79,19 @@ class Screen:
maxY = max(y, maxY)
self.size = (0,0, maxX, maxY)
self.sizeValid = True
- print self.size
- return (0, 0, maxX+100, maxY+100) #TODO: cleaner
+ return (0, 0, maxX, maxY)
#private
def processResponse(self, responseInfo, currentTime=None): #we need to make a new dict for
#each to prevent interference
- #[strip.respond(dict(responseInfo)) for strip in self.pixelStrips]
if currentTime == None:
currentTime = timeops.time()
- print 'cachetime fail'
if type(responseInfo) != type(dict()):
pass
if 'Mapper' in responseInfo:
mapper = compReg.getComponent(responseInfo['Mapper'])
else:
mapper = compReg.getComponent(Strings.DEFAULT_MAPPER)
- #if type(mapper) != type(PixelMapper):
- # raise Exception('No default mapper specified.')
pixelWeightList = mapper.mapEvent(responseInfo['Location'], self)
main_log.debug('Screen processing response. ' + str(len(pixelWeightList)) + ' events\
generated')
diff --git a/pixelevents/SynchTestEvent.py b/pixelevents/SynchTestEvent.py
new file mode 100644
index 0000000..3e7ed0c
--- /dev/null
+++ b/pixelevents/SynchTestEvent.py
@@ -0,0 +1,15 @@
+from operationscore.PixelEvent import *
+class SynchTestEvent(PixelEvent):
+ """SynchTestEvent is an event to test the synchronization of the power supplies"""
+ def initEvent(self):
+ self.eventstate = 0
+ self.cachedDelay = 0
+ def state(self, timeDelay):
+ if timeDelay != self.cachedDelay:
+ self.eventstate += 1
+ self.cachedDelay = timeDelay
+ color = [0]*3
+ color[self.eventstate % 3] = 150
+ if self.eventstate > 500:
+ self.eventstate = 0
+ return color
diff --git a/pixelmappers/WindGaussianMapper.py b/pixelmappers/WindGaussianMapper.py
new file mode 100755
index 0000000..c5d77ca
--- /dev/null
+++ b/pixelmappers/WindGaussianMapper.py
@@ -0,0 +1,18 @@
+from operationscore.PixelMapper import *
+import util.Geo as Geo
+import math
+class WindGaussianMapper(PixelMapper):
+ def mappingFunction(self, eventLocation, screen):
+ returnPixels = [] #TODO: consider preallocation and trimming
+ [x,y] = eventLocation
+ potentialPixels = screen.pixelsInRange(x-self.CutoffDist, x)
+ for (xloc,pixel) in screen.pixelsInRange(x-self.CutoffDist, x):
+ pixelDistx = math.fabs(pixel.location[0] - x)
+ pixelDisty = math.fabs(pixel.location[1] - y)
+ if pixelDistx < self.CutoffDist:
+ if pixelDisty < 30:
+ w = Geo.windtrail(pixelDistx, pixelDisty, self.Height, 0, self.Width)
+ if w > self.MinWeight:
+ returnPixels.append((pixel, w))
+
+ return returnPixels
diff --git a/renderers/IndoorRenderer.py b/renderers/IndoorRenderer.py
index 531a732..710ca43 100644
--- a/renderers/IndoorRenderer.py
+++ b/renderers/IndoorRenderer.py
@@ -21,7 +21,7 @@ class IndoorRenderer(Renderer):
for stripId in stripsInPowerSupply:
self.stripLocations[stripId] = (ip, \
stripsInPowerSupply[stripId])
-
+ self.broadSocket = network.getBroadcastSocket(6038)
def render(self, lightSystem, currentTime=timeops.time()):
#try:
for pixelStrip in lightSystem.pixelStrips:
@@ -32,4 +32,9 @@ class IndoorRenderer(Renderer):
self.sockets[ip] = network.getConnectedSocket(ip,sock_port)
packet = composer.composePixelStripPacket(pixelStrip, port, currentTime)
self.sockets[ip].send(packet, 0x00)
+
+ synchPacket = composer.composeSynchPacket()
+ #pdb.set_trace()
+ #self.broadSocket.sendto(synchPacket, ('10.0.32.255', 6038))
+
diff --git a/testosc.py b/testosc.py
deleted file mode 100755
index cea03f4..0000000
--- a/testosc.py
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env python
-
-import liblo, sys
-
-# create server, listening on port 1234
-try:
- server = liblo.Server(12345)
-except liblo.ServerError, err:
- print str(err)
- sys.exit()
-
-def foo_bar_callback(path, args):
- i, f = args
- print "received message '%s' with arguments '%d' and '%f'" % (path, i, f)
-
-def foo_baz_callback(path, args, types, src, data):
- print "received message '%s'" % path
- print "blob contains %d bytes, user data was '%s'" % (len(args[0]), data)
-
-def fallback(path, args, types, src):
- print "got unknown message '%s' from '%s'" % (path, src.get_url())
- for a, t in zip(args, types):
- print "argument of type '%s': %s" % (t, a)
-
-# register method taking an int and a float
-server.add_method("/foo/bar", 'if', foo_bar_callback)
-
-# register method taking a blob, and passing user data to the callback
-server.add_method("/foo/baz", 'b', foo_baz_callback, "blah")
-
-# register a fallback for unhandled messages
-server.add_method(None, None, fallback)
-
-# loop and dispatch messages every 100ms
-while True:
- server.recv(100)
diff --git a/oscserver.py b/tests/testosc.py
index 6763f41..6763f41 100755
--- a/oscserver.py
+++ b/tests/testosc.py
diff --git a/util/ColorOps.py b/util/ColorOps.py
index 037957a..4b1162a 100644
--- a/util/ColorOps.py
+++ b/util/ColorOps.py
@@ -1,4 +1,5 @@
import random
+import colorsys
from util.TimeOps import Stopwatch
def randomColor():
return [random.randint(0,255) for i in range(3)]
@@ -11,6 +12,8 @@ def safeColor(c):
c[0] = c[0] if c[0] < 255 else 255
c[1] = c[1] if c[1] < 255 else 255
c[2] = c[2] if c[2] < 255 else 255
+
+
return c
def combineColors(colors):
@@ -23,3 +26,17 @@ def combineColors(colors):
def multiplyColor(color, percent):
return safeColor([channel*(percent) for channel in color])
+
+def floatToIntColor(rgb):
+ rgb[0] = int(rgb[0]*256 + .5)
+ rgb[1] = int(rgb[1]*256 + .5)
+ rgb[2] = int(rgb[2]*256 + .5)
+ return safeColor(rgb)
+
+def randomBrightColor():
+ hue = random.random()
+ sat = random.random()/2.0 + .5
+ val = 1.0
+ hue, sat, val = colorsys.hsv_to_rgb(hue, sat, val)
+ ret = [hue, sat, val]
+ return floatToIntColor(ret)
diff --git a/util/Geo.py b/util/Geo.py
index 05ea9fe..0dde80b 100644
--- a/util/Geo.py
+++ b/util/Geo.py
@@ -26,3 +26,9 @@ def randomLoc(boundingBox): #TODO: make less shitty
def approxexp(x):
"""Approximates exp with a 3 term Taylor Series."""
return 1+x+x**2/2+x**3/6
+
+def windtrail(x,y,height,center,width):
+ a=height
+ b=center
+ c=width
+ return a*((math.exp(-((x-b))/(c)))**2)*(math.exp(-((y))/(0.2*c)))**2
diff --git a/util/NetworkOps.py b/util/NetworkOps.py
index 8894b78..3ece763 100644
--- a/util/NetworkOps.py
+++ b/util/NetworkOps.py
@@ -8,3 +8,9 @@ def getConnectedSocket(ip,port):
except Exception as inst:
main_log.error('Network down. All network based renderers and sensors will not function.',
inst)
+
+def getBroadcastSocket(port):
+ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+ s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
+ return s
diff --git a/util/PacketComposition.py b/util/PacketComposition.py
index 7b4fe95..75ef917 100644
--- a/util/PacketComposition.py
+++ b/util/PacketComposition.py
@@ -5,7 +5,7 @@ PORTOUT = 0x0108
UNI = 0
import pdb
import util.TimeOps as timeops
-argDict = {'flags': 0, 'startcode': 0, 'pad':0}
+argDict = {'flags': 0, 'startcode': 0x0fff, 'pad':0}
def composePixelStripData(pixelStrip,currentTime=timeops.time()):
packet = bytearray()
@@ -33,10 +33,10 @@ def memoize(f):
def cachePacketHeader(port):
packet = bytearray()
subDict = dict(argDict)
- subDict['len'] = 38500 #I have no idea why this works.
+ subDict['len'] = 150 #I have no idea why this works.
subDict['port'] = port
packet.extend(portOutPacket(subDict))
- packet.append(0x0)
+# packet.append(0x0)
return packet
def composePixelStripPacket(pixelStrip,port, currentTime):
@@ -61,10 +61,19 @@ def portOut():
def portOutPayload(argDict):
payload = bytearray()
payload.extend(struct.pack('B', argDict['port']))
+ payload.extend(struct.pack('B',0))
payload.extend(struct.pack('H', argDict['flags']))
payload.extend(struct.pack('H', argDict['len']))
payload.extend(struct.pack('H', argDict['startcode']))
return payload
+def composeSynchPacket():
+ header = bytearray()
+ header.extend(struct.pack('L', MAGIC))
+ header.extend(struct.pack('H', VERSION))
+ header.extend(struct.pack('H', 0x0109))
+ header.extend(struct.pack('L', 0))
+ header.extend(struct.pack('L', 0))
+ return header
def portOutPacket(payloadArgs):
packet = bytearray()