From 2019fb2895237aa9d86450daaf6d90831189fc13 Mon Sep 17 00:00:00 2001 From: rcoh Date: Mon, 24 Jan 2011 22:44:16 -0500 Subject: Some new stuff. Fixed a bug where screen responses weren't being synchronized. Now they are. Added XYMove to do a bouncy behavior. --- LightInstallation.py | 8 ++++---- behaviors/AllPixels.py | 6 ++++++ behaviors/SingleFrame.xml | 7 +++++++ behaviors/XYMove.py | 17 +++++++++++++++++ config/6thFloor.xml | 8 ++++---- operationscore/Behavior.py | 2 ++ pixelcore/Pixel.py | 6 +++++- pixelcore/Screen.py | 17 ++++++++++++----- pixelevents/SingleFrameEvent.py | 5 ++--- pixelmappers/GaussianMapper.py | 2 ++ 10 files changed, 61 insertions(+), 17 deletions(-) create mode 100644 behaviors/AllPixels.py create mode 100644 behaviors/SingleFrame.xml create mode 100644 behaviors/XYMove.py 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 @@ + + behaviors.AddPixelEvent + + pixelevents.SingleFrameEvent + 0 + + 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 @@ - + renderers/Pygame.xml @@ -260,9 +260,9 @@ echo redshift square - decay + singleframe - False + True 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) -- cgit v1.2.3