aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar rcoh <rcoh@mit.edu>2011-01-24 22:44:16 -0500
committerGravatar rcoh <rcoh@mit.edu>2011-01-24 22:44:16 -0500
commit2019fb2895237aa9d86450daaf6d90831189fc13 (patch)
tree6dd9de45c5c2994c0a6aad2aa808092abb8f99bd
parent39de2bc415e6dc02c68018655962197a38207718 (diff)
Some new stuff. Fixed a bug where screen responses weren't being synchronized. Now they are.
Added XYMove to do a bouncy behavior.
-rw-r--r--LightInstallation.py8
-rw-r--r--behaviors/AllPixels.py6
-rw-r--r--behaviors/SingleFrame.xml7
-rw-r--r--behaviors/XYMove.py17
-rw-r--r--config/6thFloor.xml8
-rw-r--r--operationscore/Behavior.py2
-rw-r--r--pixelcore/Pixel.py6
-rw-r--r--pixelcore/Screen.py17
-rw-r--r--pixelevents/SingleFrameEvent.py5
-rw-r--r--pixelmappers/GaussianMapper.py2
10 files changed, 61 insertions, 17 deletions
diff --git a/LightInstallation.py b/LightInstallation.py
index 62d3f6a..b582bd2 100644
--- a/LightInstallation.py
+++ b/LightInstallation.py
@@ -146,19 +146,19 @@ class LightInstallation(object):
def mainLoop(self):
lastLoopTime = clock.time()
refreshInterval = 30
- runCount = 2000
- while runCount > 0 and not self.dieNow:
- runCount -= 1
+ while not self.dieNow:
loopStart = clock.time()
responses = self.evaluateBehaviors() #inputs are all queued when they
#happen, so we only need to run the behaviors
self.timer.start()
[self.screen.respond(response) for response in responses if
response != []]
- self.screen.timeStep()
+ self.screen.timeStep(loopStart)
[r.render(self.screen, loopStart) for r in self.renderers]
loopElapsed = clock.time()-loopStart
sleepTime = max(0,refreshInterval-loopElapsed)
+ main_log.debug('Loop complete in ' + str(loopElapsed) + 'ms. Sleeping for ' +\
+ str(sleepTime))
self.timer.stop()
#print self.timer.elapsed()
if sleepTime > 0:
diff --git a/behaviors/AllPixels.py b/behaviors/AllPixels.py
new file mode 100644
index 0000000..e155e55
--- /dev/null
+++ b/behaviors/AllPixels.py
@@ -0,0 +1,6 @@
+from operationscore.Behavior import *
+class AllPixels(Behavior):
+ def processResponse(self, sensorInputs, recursiveInputs):
+ for sensory in sensorInputs:#TODO: consider replicating the dict
+ sensory['Location'] = 'True'
+ return (sensorInputs, recursiveInputs)
diff --git a/behaviors/SingleFrame.xml b/behaviors/SingleFrame.xml
new file mode 100644
index 0000000..49b5dcf
--- /dev/null
+++ b/behaviors/SingleFrame.xml
@@ -0,0 +1,7 @@
+<Behavior>
+ <Class>behaviors.AddPixelEvent</Class>
+ <Args>
+ <Class>pixelevents.SingleFrameEvent</Class>
+ <z-index>0</z-index>
+ </Args>
+</Behavior>
diff --git a/behaviors/XYMove.py b/behaviors/XYMove.py
new file mode 100644
index 0000000..8acbba8
--- /dev/null
+++ b/behaviors/XYMove.py
@@ -0,0 +1,17 @@
+from operationscore.Behavior import *
+import util.Geo as Geo
+class XYMove(Behavior):
+ def processResponse(self, sensor, recurs):
+ ret = []
+ for loc in sensor:
+ oploc = dict(loc)
+ self.insertStepIfMissing(oploc)
+ oploc['Location'] = Geo.addLocations((oploc['XStep'], oploc['YStep']), oploc['Location'])
+ ret.append(oploc)
+ return (ret, [])
+ def insertStepIfMissing(self, data):
+ if not 'XStep' in data:
+ data['XStep'] = self['XStep']
+ if not 'YStep' in data:
+ data['YStep'] = self['YStep']
+
diff --git a/config/6thFloor.xml b/config/6thFloor.xml
index 4c31892..3f734d9 100644
--- a/config/6thFloor.xml
+++ b/config/6thFloor.xml
@@ -29,9 +29,9 @@
</PixelMapper>
</PixelMapperConfiguration>
<RendererConfiguration>
- <!--<Renderer>
+ <Renderer>
<InheritsFrom>renderers/60StripSeq.xml</InheritsFrom>
- </Renderer>-->
+ </Renderer>
<Renderer>
<InheritsFrom>renderers/Pygame.xml</InheritsFrom>
</Renderer>
@@ -260,9 +260,9 @@
<Id>echo</Id>
<Id>redshift</Id>
<Id>square</Id>
- <Id>decay</Id>
+ <Id>singleframe</Id>
</ChainedBehaviors>
- <RenderToScreen>False</RenderToScreen>
+ <RenderToScreen>True</RenderToScreen>
</Args>
</Behavior>
<Behavior Id="running">
diff --git a/operationscore/Behavior.py b/operationscore/Behavior.py
index 882a290..b3f7342 100644
--- a/operationscore/Behavior.py
+++ b/operationscore/Behavior.py
@@ -9,6 +9,7 @@
import pdb
from operationscore.SmootCoreObject import *
+from logger import main_log
#timeStep is called on every iteration of the LightInstallation
#addInput is called on each individual input received, and the inputs queue
class Behavior(SmootCoreObject):
@@ -56,4 +57,5 @@ class Behavior(SmootCoreObject):
self.recursiveResponseQueue)
self.sensorResponseQueue = []
self.recursiveResponseQueue = recursions
+ main_log.debug(self['Id'] + ' Ouputs ' + str(outputs))
return self.addMapperToResponse(outputs)
diff --git a/pixelcore/Pixel.py b/pixelcore/Pixel.py
index 7260e56..1fbea2c 100644
--- a/pixelcore/Pixel.py
+++ b/pixelcore/Pixel.py
@@ -52,7 +52,11 @@ class Pixel:
(zindex,scale,event) = self.events[eventTime]
eventResult = event.state(currentTime-eventTime)
if eventResult != None:
- colors.append(color.multiplyColor(eventResult,scale))
+ scaledEvent = color.multiplyColor(eventResult,scale)
+ if (scaledEvent[0] + scaledEvent[1] + scaledEvent[2]) < 5:
+ deadEvents.append(eventTime)
+ else:
+ colors.append(scaledEvent)
else:
deadEvents.append(eventTime)
diff --git a/pixelcore/Screen.py b/pixelcore/Screen.py
index cfadee8..a6fc8c4 100644
--- a/pixelcore/Screen.py
+++ b/pixelcore/Screen.py
@@ -49,11 +49,15 @@ class Screen:
#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.
- def timeStep(self):
+ #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):
+ if currentTime == None:
+ currentTime = timeops.time()
tempQueue = list(self.responseQueue)
self.responseQueue = []
for response in tempQueue:
- self.processResponse(response)
+ self.processResponse(response, currentTime)
#public
def respond(self, responseInfo):
@@ -73,13 +77,15 @@ 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
#private
- def processResponse(self, responseInfo): #we need to make a new dict for
+ 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:
@@ -89,7 +95,8 @@ class Screen:
#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')
PixelEvent.addPixelEventIfMissing(responseInfo)
- currentTime = timeops.time()
for (pixel, weight) in pixelWeightList:
pixel.processInput(responseInfo['PixelEvent'], 0,weight, currentTime) #TODO: z-index
diff --git a/pixelevents/SingleFrameEvent.py b/pixelevents/SingleFrameEvent.py
index 97a2681..767f403 100644
--- a/pixelevents/SingleFrameEvent.py
+++ b/pixelevents/SingleFrameEvent.py
@@ -3,9 +3,8 @@ class SingleFrameEvent(PixelEvent):
def initEvent(self):
self.timeState = -1
def state(self, timeDelay):
- print 'singlehit'
-
- if self.timeState == (-1 or timeDelay):
+ if self.timeState == -1:
self.timeState = timeDelay
+ if self.timeState == timeDelay:
return self.Color
return None
diff --git a/pixelmappers/GaussianMapper.py b/pixelmappers/GaussianMapper.py
index 686ebcd..c82f243 100644
--- a/pixelmappers/GaussianMapper.py
+++ b/pixelmappers/GaussianMapper.py
@@ -4,6 +4,8 @@ class GaussianMapper(PixelMapper):
def mappingFunction(self, eventLocation, screen):
returnPixels = [] #TODO: consider preallocation and trimming
[x,y] = eventLocation
+ potentialPixels = screen.pixelsInRange(x-self.CutoffDist, \
+ x+self.CutoffDist)
for (x,pixel) in screen.pixelsInRange(x-self.CutoffDist, \
x+self.CutoffDist):
pixelDist = Geo.dist(pixel.location, eventLocation)