aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar rcoh <rcoh@mit.edu>2010-12-08 16:39:50 -0500
committerGravatar rcoh <rcoh@mit.edu>2010-12-08 16:39:50 -0500
commitb335b746523ffd59db1402b097a802b3fd99eaac (patch)
tree74333be1820f3d2666358c3b009beb14bf929256
parent353ab16db64c86122c0fcb9e1852b85c14b354b8 (diff)
Code for the demo. Everything works afaik. Contains a couple more optimizations. Contains modify param behavior. Improved support for recursive hooks. Modifications to SmootCoreObject to get us closer to a fully multi-threaded system. This should be the last commit directly to master. All further commits should be on subranches and get merged.
-rw-r--r--LightInstallation.py2
-rw-r--r--Util.py12
-rw-r--r--behaviors/BehaviorChain.py11
-rw-r--r--behaviors/ColorChangerBehavior.py5
-rw-r--r--behaviors/ModifyParam.py27
-rw-r--r--behaviors/RecursiveDecay.py4
-rw-r--r--behaviors/RunningBehavior.py6
-rw-r--r--config/LightInstallationConfig.xml18
-rw-r--r--config/Outdoor.xml252
-rw-r--r--inputs/PygameInput.py1
-rw-r--r--operationscore/Behavior.py2
-rw-r--r--operationscore/Input.py15
-rw-r--r--operationscore/Renderer.py2
-rw-r--r--operationscore/SmootCoreObject.py14
-rw-r--r--pixelcore/Pixel.py1
-rw-r--r--pixelcore/Screen.py4
-rw-r--r--pixelevents/DecayEvent.py1
-rw-r--r--pixelmappers/GaussianMapper.py5
18 files changed, 337 insertions, 45 deletions
diff --git a/LightInstallation.py b/LightInstallation.py
index 8f71cf0..e4adab7 100644
--- a/LightInstallation.py
+++ b/LightInstallation.py
@@ -87,7 +87,7 @@ class LightInstallation:
#self.screen.allOn()
lastLoopTime = Util.time()
refreshInterval = 30
- runCount = 1000
+ runCount = 10000
while runCount > 0:
runCount -= 1
loopStart = Util.time()
diff --git a/Util.py b/Util.py
index ea75b05..07ce545 100644
--- a/Util.py
+++ b/Util.py
@@ -17,6 +17,7 @@ MAGICHASH = 0x69000420
PORTOUT = 0x0108
classArgsMem = {}
UNI = 0
+colorByteMem = {}
CONFIG_PATH = 'config/'
kinetDict = {'flags': 0, 'startcode': 0, 'pad':0}
componentDict = {}
@@ -75,6 +76,7 @@ def loadConfigFile(fileName):
def fileToDict(fileName):
fileText = ''
try:
+ print 'File Read'
with open(fileName) as f:
for line in f:
fileText += line.rstrip('\n').lstrip('\t') + ' '
@@ -95,7 +97,7 @@ def safeColor(c):
def combineColors(c1,c2):
return safeColor([c1[i]+c2[i] for i in range(min(len(c1),len(c2)))])
def multiplyColor(color, percent):
- return safeColor(tuple([channel*(percent) for channel in color]))
+ return safeColor([channel*(percent) for channel in color])
#parses arguments into python objects if possible, otherwise leaves as strings
def generateArgDict(parentNode, recurse=False):
args = {}
@@ -159,13 +161,17 @@ def composePixelStripData(pixelStrip):
for channel in color: #skip the last value, its an
#alpha value
packet.append(struct.pack('B', channel))
- #pdb.set_trace()
return packet
+# packet = [0]*len(pixelStrip.pixels)*3 #preallocate for speed
+# for i in range(len(pixelStrip.pixels)):
+#color = pixelStrip.pixels[i].state()
+#packet[i:i+2] = color
+# return bytearray(packet)
def composePixelStripPacket(pixelStrip,port):
packet = bytearray()
data = composePixelStripData(pixelStrip)
subDict = dict(kinetDict)
- subDict['len'] = 38399 #I have no idea why this works.
+ subDict['len'] = 38000 #I have no idea why this works.
subDict['port'] = port
#pdb.set_trace()
packet.extend(kinetPortOutPacket(subDict))
diff --git a/behaviors/BehaviorChain.py b/behaviors/BehaviorChain.py
index 8b5cb1d..fe50573 100644
--- a/behaviors/BehaviorChain.py
+++ b/behaviors/BehaviorChain.py
@@ -20,8 +20,11 @@ class BehaviorChain(Behavior):
if behaviorId in self.hooks: #process recursive hook if there is one
hookBehavior = Util.getComponentById(self.hooks[behaviorId])
- (response, recurrence) = \
- hookBehavior.immediateProcessInput(response,
- recurrence)
- self.feedback[behaviorId] = recurrence
+#we feed its recurrence in as input to the behavior.
+ (recurrence, hookRecurrence) = \
+ hookBehavior.immediateProcessInput(recurrence, \
+ [])
+ if hookRecurrence != []:
+ print 'Hook recurrences are not currently supported. Implement it yourself or bug russell'
+ self.feedback[behaviorId] = recurrence
return response
diff --git a/behaviors/ColorChangerBehavior.py b/behaviors/ColorChangerBehavior.py
index 12ef6f4..a3b1739 100644
--- a/behaviors/ColorChangerBehavior.py
+++ b/behaviors/ColorChangerBehavior.py
@@ -7,8 +7,9 @@ class ColorChangerBehavior(Behavior):
for sensory in sensorInputs:
newDict = dict(sensory) #don't run into shallow copy issues
if self['ColorList'] != None:
- newDict['Color'] = Util.chooseRandomColor(self['ColorList'])
+ newDict['Color'] = Util.chooseRandomColor(self['ColorList']) #TODO: this doesn't work.
else:
newDict['Color'] = Util.randomColor()
+#newDict['Color'] = (255,0,0)
ret.append(newDict)
- return ret
+ return (ret, recursiveInputs)
diff --git a/behaviors/ModifyParam.py b/behaviors/ModifyParam.py
new file mode 100644
index 0000000..38b8cd5
--- /dev/null
+++ b/behaviors/ModifyParam.py
@@ -0,0 +1,27 @@
+from operationscore.Behavior import *
+import Util
+import pdb
+#Class to perform a given operation on some element of an argDict. Designed to be used a recursive hook, but can serve sensor-based functions as well. Specify ParamType (Sensor or Recurse), ParamName, and ParamOp, (a valid python statement with the old value represented as {val})
+class ModifyParam(Behavior):
+ def processResponse(self, sensorInputs, recursiveInputs):
+ paramType = self['ParamType']
+ paramName = self['ParamName']
+ paramOp = self['ParamOp']
+ if paramType == 'Sensor':
+ searchSet = sensorInputs
+ elif paramType == 'Recurse':
+ searchSet = recursiveInputs
+ else:
+ raise Exception('Unknown Param Type')
+ for behaviorInput in searchSet:
+ if paramName in behaviorInput:
+ try:
+ paramOp = paramOp.replace('{val}', 'behaviorInput[paramName]') #convert the {val} marker to something we can execute
+ behaviorInput[paramName] = eval(paramOp)
+ except:
+ raise Exception('Bad operation. Use things like \'{val}*5\', \'{val}+5\', exp({val}) etc.')
+ if paramType == 'Sensor': #return accordingly
+ return (searchSet, recursiveInputs)
+ if paramType == 'Recurse':
+ return (sensorInputs, searchSet)
+
diff --git a/behaviors/RecursiveDecay.py b/behaviors/RecursiveDecay.py
index b119b85..ee38bc4 100644
--- a/behaviors/RecursiveDecay.py
+++ b/behaviors/RecursiveDecay.py
@@ -2,11 +2,11 @@ from operationscore.Behavior import *
class RecursiveDecay(Behavior):
def processResponse(self, sensorInputs, recursiveInputs):
ret = []
- for response in recursiveInputs:
+ for response in sensorInputs:
if not 'ResponsesLeft' in response:
response['ResponsesLeft'] = self['InitialResponseCount']
else:
response['ResponsesLeft'] -= 1
if response['ResponsesLeft'] > 0:
ret.append(response)
- return (sensorInputs, ret) #no direct ouput
+ return (ret, recursiveInputs) #no direct ouput
diff --git a/behaviors/RunningBehavior.py b/behaviors/RunningBehavior.py
index 255ce69..3d82d29 100644
--- a/behaviors/RunningBehavior.py
+++ b/behaviors/RunningBehavior.py
@@ -10,11 +10,13 @@ class RunningBehavior(Behavior):
outDict = dict(recurInput)
if not 'Dir' in outDict:
outDict['Dir'] = 1 #to the right
+ if not 'StepSize' in outDict:
+ outDict['StepSize'] = self['StepSize']
outDict['Location']= Util.addLocations(outDict['Location'],
- (self['StepSize']*outDict['Dir'],0))
+ (outDict['StepSize']*outDict['Dir'],0))
if not Util.pointWithinBoundingBox(outDict['Location'], \
Util.getScreen().getSize()):
- outDict['Dir'] *= -1
+ outDict['Dir'] *= -1
ret.append(outDict)
ret += newResponses
return (ret, ret)
diff --git a/config/LightInstallationConfig.xml b/config/LightInstallationConfig.xml
index dfa05d7..5067335 100644
--- a/config/LightInstallationConfig.xml
+++ b/config/LightInstallationConfig.xml
@@ -7,13 +7,13 @@
<Args><!--Any args the layout class needs. This go as
elements of a dictionary that gets passed to the Layout machinery-->
<Id>strip1</Id>
- <zigLength>25</zigLength>
+ <zigLength>250</zigLength>
<zigAxis>X</zigAxis>
<yDirection>-1</yDirection>
<pixelToPixelSpacing>12</pixelToPixelSpacing>
- <spacing>12</spacing> <!--we can space at any value less the
+ <spacing>5</spacing> <!--we can space at any value less the
l2lspacing-->
- <numPixels>50</numPixels>
+ <numPixels>500</numPixels>
<originLocation>(10,20)</originLocation>
</Args>
</PixelStrip>
@@ -21,12 +21,12 @@
<Class>layouts.ZigzagLayout</Class>
<Args>
<Id>strip2</Id>
- <zigLength>25</zigLength>
+ <zigLength>250</zigLength>
<zigAxis>X</zigAxis>
<yDirection>1</yDirection>
<pixelToPixelSpacing>12</pixelToPixelSpacing>
- <spacing>12</spacing>
- <numPixels>50</numPixels>
+ <spacing>5</spacing>
+ <numPixels>500</numPixels>
<originLocation>(10,30)</originLocation>
</Args>
</PixelStrip>
@@ -44,8 +44,8 @@
<Class>pixelmappers.GaussianMapper</Class>
<Args>
<Id>gaussmap</Id>
- <CutoffDist>30</CutoffDist>
- <Width>5</Width>
+ <CutoffDist>20</CutoffDist>
+ <Width>3</Width>
<Height>1</Height>
</Args>
</PixelMapper>
@@ -121,7 +121,7 @@
<Args>
<Id>decay</Id>
<DecayType>Exponential</DecayType>
- <Coefficient>.001</Coefficient>
+ <Coefficient>.01</Coefficient>
<z-index>0</z-index>
<RenderToScreen>False</RenderToScreen>
<Inputs>
diff --git a/config/Outdoor.xml b/config/Outdoor.xml
new file mode 100644
index 0000000..7f054f0
--- /dev/null
+++ b/config/Outdoor.xml
@@ -0,0 +1,252 @@
+<!---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>
+ <PixelConfiguration>
+ <PixelStrip>
+ <Class>layouts.LineLayout</Class>
+ <Args>
+ <Id>strip1</Id>
+ <pixelToPixelSpacing>4</pixelToPixelSpacing>
+ <spacing>4</spacing>
+ <numPixels>50</numPixels>
+ <originLocation>(10,20)</originLocation>
+ </Args>
+ </PixelStrip>
+ <PixelStrip>
+ <Class>layouts.LineLayout</Class>
+ <Args>
+ <Id>strip2</Id>
+ <pixelToPixelSpacing>4</pixelToPixelSpacing>
+ <spacing>4</spacing>
+ <numPixels>50</numPixels>
+ <originLocation>(10,24)</originLocation>
+ </Args>
+ </PixelStrip>
+ <PixelStrip>
+ <Class>layouts.LineLayout</Class>
+ <Args>
+ <Id>strip3</Id>
+ <pixelToPixelSpacing>4</pixelToPixelSpacing>
+ <spacing>4</spacing>
+ <numPixels>50</numPixels>
+ <originLocation>(10,28)</originLocation>
+ </Args>
+ </PixelStrip>
+ <PixelStrip>
+ <Class>layouts.LineLayout</Class>
+ <Args>
+ <Id>strip4</Id>
+ <pixelToPixelSpacing>4</pixelToPixelSpacing>
+ <spacing>4</spacing>
+ <numPixels>50</numPixels>
+ <originLocation>(10,32)</originLocation>
+ </Args>
+ </PixelStrip>
+ <PixelStrip>
+ <Class>layouts.LineLayout</Class>
+ <Args>
+ <Id>strip5</Id>
+ <pixelToPixelSpacing>4</pixelToPixelSpacing>
+ <spacing>4</spacing>
+ <numPixels>50</numPixels>
+ <originLocation>(10,36)</originLocation>
+ </Args>
+ </PixelStrip>
+ <PixelStrip>
+ <Class>layouts.LineLayout</Class>
+ <Args>
+ <Id>strip6</Id>
+ <pixelToPixelSpacing>4</pixelToPixelSpacing>
+ <spacing>4</spacing>
+ <numPixels>50</numPixels>
+ <originLocation>(10,40)</originLocation>
+ </Args>
+ </PixelStrip>
+ </PixelConfiguration>
+ <!--<PixelMapperConfiguration>
+ <PixelMapper>
+ <Class>pixelmappers.SimpleMapper</Class>
+ <Args>
+ <Id>simplemap</Id>
+ </Args>
+ </PixelMapper>
+ </PixelMapperConfiguration>-->
+ <PixelMapperConfiguration>
+ <PixelMapper>
+ <Class>pixelmappers.GaussianMapper</Class>
+ <Args>
+ <Id>gaussmap</Id>
+ <CutoffDist>20</CutoffDist>
+ <Width>3</Width>
+ <Height>1</Height>
+ </Args>
+ </PixelMapper>
+ </PixelMapperConfiguration>
+ <RendererConfiguration>
+ <Renderer>
+ <Class>renderers.PygameRenderer</Class>
+ <Args>
+ <Id>pygamerender</Id>
+ <displaySize>(1300,50)</displaySize>
+ </Args>
+ </Renderer>
+ <Renderer>
+ <Class>renderers.IndoorRenderer</Class>
+ <Args>
+ <Id>indoorRenderer</Id>
+ <PowerSupply>
+ <IP>10.31.255.233</IP>
+ <PortMapping>{'strip1':1, 'strip2':2}</PortMapping>
+ </PowerSupply>
+ <PowerSupply>
+ <IP>10.32.97.17</IP>
+ <PortMapping>{'strip3':1, 'strip4':2}</PortMapping>
+ </PowerSupply>
+ <PowerSupply>
+ <IP>10.32.96.211</IP>
+ <PortMapping>{'strip5':1, 'strip6':2}</PortMapping>
+ </PowerSupply>
+ </Args>
+ </Renderer>
+ </RendererConfiguration>
+ <InputConfiguration>
+ <InputElement>
+ <Class>inputs.PygameInput</Class>
+ <Args><!--Passed as a dictionary-->
+ <Id>pygame</Id>
+ <RefreshInterval>100</RefreshInterval>
+ </Args>
+ </InputElement>
+ <InputElement>
+ <Class>inputs.PygameInput</Class>
+ <Args>
+ <Id>followmouse</Id>
+ <RefreshInterval>10</RefreshInterval>
+ <FollowMouse>True</FollowMouse>
+ </Args>
+ </InputElement>
+ <InputElement>
+ <Class>inputs.UDPInput</Class>
+ <Args>
+ <Id>UDP</Id>
+ <Port>6038</Port>
+ <RefreshInterval>100</RefreshInterval>
+ </Args>
+ </InputElement>
+ </InputConfiguration>
+ <BehaviorConfiguration>
+ <Behavior>
+ <Class>behaviors.EchoBehavior</Class>
+ <Args>
+ <Id>echo</Id>
+ <z-index>0</z-index>
+ <RenderToScreen>False</RenderToScreen>
+ <Inputs>
+ </Inputs>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.ColorChangerBehavior</Class>
+ <Args>
+ <Id>colorchange</Id>
+ <z-index>0</z-index>
+ <RenderToScreen>False</RenderToScreen>
+ <!--<ColorList>
+ <Color>(255,0,0)</Color>
+ </ColorList>-->
+ <Inputs>
+ <Id>pygame</Id>
+ </Inputs>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.DecayBehavior</Class>
+ <Args>
+ <Id>decay</Id>
+ <DecayType>Exponential</DecayType>
+ <Coefficient>.01</Coefficient>
+ <z-index>0</z-index>
+ <RenderToScreen>False</RenderToScreen>
+ <Inputs>
+ </Inputs>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.DebugBehavior</Class>
+ <Args>
+ <Id>debug</Id>
+ <z-index>0</z-index>
+ <Inputs>
+ <Id>pygame</Id>
+ </Inputs>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.RecursiveDecay</Class>
+ <Args>
+ <Id>recursivedecay</Id>
+ <InitialResponseCount>70</InitialResponseCount>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.BehaviorChain</Class>
+ <Args>
+ <Id>runcolordecay</Id>
+ <Inputs>
+ <Id>pygame</Id>
+ </Inputs>
+ <ChainedBehaviors>
+ <Id>colorchange</Id>
+ <Id>running</Id>
+ <Id>decay</Id>
+ </ChainedBehaviors>
+ <RecursiveHooks>{'running':'acceleratedie'}</RecursiveHooks>
+ <RenderToScreen>True</RenderToScreen>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.ModifyParam</Class>
+ <Args>
+ <Id>accelerate</Id>
+ <ParamType>Sensor</ParamType>
+ <ParamName>StepSize</ParamName>
+ <ParamOp>{val}*1.05</ParamOp>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.BehaviorChain</Class>
+ <Args>
+ <Id>acceleratedie</Id>
+ <ChainedBehaviors>
+ <Id>accelerate</Id>
+ <Id>recursivedecay</Id>
+ </ChainedBehaviors>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.BehaviorChain</Class>
+ <Args>
+ <Id>mousechaser</Id>
+ <Inputs>
+ <Id>followmouse</Id>
+ </Inputs>
+ <ChainedBehaviors>
+ <Id>echo</Id>
+ <Id>colorchange</Id>
+ <Id>decay</Id>
+ </ChainedBehaviors>
+ <RenderToScreen>True</RenderToScreen>
+ </Args>
+ </Behavior>
+ <Behavior>
+ <Class>behaviors.RunningBehavior</Class>
+ <Args>
+ <Id>running</Id>
+ <Inputs>
+ <Id>pygame</Id>
+ </Inputs>
+ <StepSize>1</StepSize>
+ <RenderToScreen>False</RenderToScreen>
+ </Args>
+ </Behavior>
+ </BehaviorConfiguration>
+</LightInstallation>
diff --git a/inputs/PygameInput.py b/inputs/PygameInput.py
index e07592b..1f438d6 100644
--- a/inputs/PygameInput.py
+++ b/inputs/PygameInput.py
@@ -9,6 +9,7 @@ class PygameInput(Input):
#try:
if self['FollowMouse']:
self.respond({Util.location: pygame.mouse.get_pos()})
+ return
for event in pygame.event.get():
if event.type is KEYDOWN:
self.respond({Util.location: (5,5),'Key': event.key})
diff --git a/operationscore/Behavior.py b/operationscore/Behavior.py
index 83d2e7d..3bdf1ec 100644
--- a/operationscore/Behavior.py
+++ b/operationscore/Behavior.py
@@ -41,7 +41,7 @@ class Behavior(SmootCoreObject):
[self.addInput(sensorInput) for sensorInput in sensorInputs]
else:
self.addInput(sensorInputs)
- def timeStep(self):
+ def timeStep(self): #TODO: type checking. clean this up
responses = self.processResponse(self.sensorResponseQueue, \
self.recursiveResponseQueue)
if type(responses) == type(tuple()) and len(responses) == 2:
diff --git a/operationscore/Input.py b/operationscore/Input.py
index 9ee59f8..2144678 100644
--- a/operationscore/Input.py
+++ b/operationscore/Input.py
@@ -1,4 +1,5 @@
import threading,time,Util
+from operationscore.SmootCoreObject import *
#Abstract class for inputs. Inheriting classes should call "respond" to raise
#their event. Inheriting classes MUST define sensingLoop. Called at the
#interval specified in RefreshInterval while the input is active. For example, if you are writing
@@ -6,7 +7,7 @@ import threading,time,Util
#Inheriting classes MAY define inputInit. This is called before the loop
#begins.
import pdb
-class Input(threading.Thread):
+class Input(SmootCoreObject):
#Event scope is a function pointer the function that will get called when
#an Parent is raised.
def __init__(self, argDict):
@@ -19,16 +20,6 @@ class Input(threading.Thread):
self.inputInit()
threading.Thread.__init__(self)
self.daemon = True #This kills this thread when the main thread stops
- #CHEATING until I can get multiple inheritence working
- def __setitem__(self,k, item):
- self.argDict[k] = item
- def __getitem__(self, item):
- if item in self.argDict:
- return self.argDict[item]
- else:
- return None
- def __getiter__(self):
- return self.argDict.__getiter__()
def respond(self, eventDict):
#if eventDict != []:
#pdb.set_trace()
@@ -48,7 +39,9 @@ class Input(threading.Thread):
def run(self):
while self.parentAlive():
time.sleep(self.argDict['RefreshInterval']/float(1000))
+ self.acquireLock()
self.sensingLoop()
+ self.releaseLock()
def sensingLoop(self):
pass
def inputInit(self):
diff --git a/operationscore/Renderer.py b/operationscore/Renderer.py
index 11fd8ca..8e31f8b 100644
--- a/operationscore/Renderer.py
+++ b/operationscore/Renderer.py
@@ -2,10 +2,12 @@
#Inheriting classes MUST define render which takes a light system and renders it.
#Inheriting classes may define initRenderer which is called after the dictionary
#is pulled from config.
+#TODO: multithreaded-rendering
from operationscore.SmootCoreObject import *
class Renderer(SmootCoreObject):
def init(self):
self.initRenderer()
+ threading.Thread.__init__(self)
def render(lightSystem):
pass
def initRenderer(self):
diff --git a/operationscore/SmootCoreObject.py b/operationscore/SmootCoreObject.py
index d29e710..8514b3e 100644
--- a/operationscore/SmootCoreObject.py
+++ b/operationscore/SmootCoreObject.py
@@ -1,16 +1,24 @@
import Util
import pdb
-class SmootCoreObject:
- def __init__(self, argDict):
+import threading
+import thread
+class SmootCoreObject(threading.Thread):
+ def __init__(self, argDict, skipValidation = False):
self.argDict = argDict
self.validateArgs(self.className()+'.params')
+ self.lock = thread.allocate_lock()
self.init() #call init of inheriting class
# self.__setitem__ = self.argDict.__setitem__
# self.__getitem__ = self.argDict.__getitem__
def init(self):
pass
+ def acquireLock(self):
+ self.lock = thread.allocate_lock() #TODO: fix.
+ self.lock.acquire()
+ def releaseLock(self):
+ self.lock.release()
def className(self):
- return str(self.__class__).split('.')[-1]
+ return str(self.__class__).split('.')[-1] #TODO: this doesn't work.
def __setitem__(self,k, item):
self.argDict[k] = item
def __getitem__(self, item):
diff --git a/pixelcore/Pixel.py b/pixelcore/Pixel.py
index 4c8ec89..ba87dff 100644
--- a/pixelcore/Pixel.py
+++ b/pixelcore/Pixel.py
@@ -47,6 +47,7 @@ class Pixel:
else:
deadEvents.append(eventTime)
[self.events.pop(event) for event in deadEvents]
+ resultingColor = [int(round(c)) for c in resultingColor]
self.memState = tuple(resultingColor)
return tuple(resultingColor)
def __str__(self):
diff --git a/pixelcore/Screen.py b/pixelcore/Screen.py
index 71b9b0b..92805a8 100644
--- a/pixelcore/Screen.py
+++ b/pixelcore/Screen.py
@@ -59,9 +59,9 @@ class Screen:
minY = min(y, minY)
maxY = max(y, maxY)
- self.size = (minX, minY, maxX, maxY)
+ self.size = (0,0, maxX, maxY)
self.sizeValid = True
- return (minX, minY, maxX, maxY)
+ return (0, 0, maxX+100, maxY+100) #TODO: cleaner
#private
def processResponse(self, responseInfo): #we need to make a new dict for
#each to prevent interference
diff --git a/pixelevents/DecayEvent.py b/pixelevents/DecayEvent.py
index 01255be..9a7c600 100644
--- a/pixelevents/DecayEvent.py
+++ b/pixelevents/DecayEvent.py
@@ -2,7 +2,6 @@ from operationscore.PixelEvent import *
import Util, math
class DecayEvent(PixelEvent):
def initEvent(self):
- self.validateArgs('DecayEvent.params')
self['Coefficient'] = abs(self['Coefficient'])
def state(self,timeDelay):
if self['DecayType'] == 'Exponential':
diff --git a/pixelmappers/GaussianMapper.py b/pixelmappers/GaussianMapper.py
index 1cf9e88..04bd447 100644
--- a/pixelmappers/GaussianMapper.py
+++ b/pixelmappers/GaussianMapper.py
@@ -2,15 +2,12 @@ from operationscore.PixelMapper import *
import Util
class GaussianMapper(PixelMapper):
def mappingFunction(self, eventLocation, screen):
- returnPixels = []
+ returnPixels = [] #TODO: consider preallocation and trimming
[x,y] = eventLocation
for (x,pixel) in screen.pixelsInRange(x-self['CutoffDist'], \
x+self['CutoffDist']):
pixelDist = Util.dist(pixel.location, eventLocation)
if pixelDist < self['CutoffDist']:
w = Util.gaussian(pixelDist, self['Height'], 0, self['Width'])
- if w>1:
- #pdb.set_trace()
- pass
returnPixels.append((pixel, w))
return returnPixels