diff options
author | eugue <eug.sun@gmail.com> | 2011-01-24 14:41:38 -0500 |
---|---|---|
committer | eugue <eug.sun@gmail.com> | 2011-01-24 14:41:38 -0500 |
commit | 00e836cfa4e2652d724972585d661143142af002 (patch) | |
tree | f612ea43024f13dc8c16f192735676e9976630fc | |
parent | d39f871cf9fcce13c6db315052a4951f692719f9 (diff) |
merge with biginstall
42 files changed, 1001 insertions, 97 deletions
diff --git a/LightInstallation.py b/LightInstallation.py index 2eb03c9..7f98473 100644 --- a/LightInstallation.py +++ b/LightInstallation.py @@ -97,6 +97,8 @@ class LightInstallation(object): def registerComponents(self, components): for component in components: + cid = compReg.registerComponent(component) + main_log.debug(cid + ' registered') cid = component['Id'] if cid == None: #TODO: determine if componenent is critical, and if so, die main_log.error('Components must be registered with Ids. Component not registered') @@ -118,7 +120,7 @@ class LightInstallation(object): exec('from ' + module+'.'+className + ' import *') main_log.debug(module +'.' +className + 'imported') except Exception as inst: - main_log.error('Error importing ' + module+'.'+'.className. Component not\ + main_log.error('Error importing ' + module+'.'+className+ '. Component not\ initialized.') main_log.error(str(inst)) continue @@ -1,4 +1,4 @@ import cProfile from LightInstallation import main -command = """main(['', 'config/Outdoor.xml'])""" +command = """main(['', 'config/6thFloor.xml'])""" cProfile.runctx(command, globals(), locals(), filename="smootlight.profile") @@ -1,5 +1,9 @@ import unittest from unittest import TestLoader import tests.TestConfigLoaders +import tests.TestComponentRegistry testSuite = TestLoader().loadTestsFromModule(tests.TestConfigLoaders) unittest.TextTestRunner(verbosity=2).run(testSuite) + +testSuite = TestLoader().loadTestsFromModule(tests.TestComponentRegistry) +unittest.TextTestRunner(verbosity=2).run(testSuite) diff --git a/behaviors/Accelerate.xml b/behaviors/Accelerate.xml index c78195b..f9de077 100644 --- a/behaviors/Accelerate.xml +++ b/behaviors/Accelerate.xml @@ -3,6 +3,6 @@ <Args> <ParamType>Sensor</ParamType> <ParamName>StepSize</ParamName> - <ParamOp>{val}*1.01</ParamOp> + <ParamOp>{val}*1.1</ParamOp> </Args> </Behavior> diff --git a/behaviors/AddPixelEvent.py b/behaviors/AddPixelEvent.py index bf3cfff..7f134e1 100644 --- a/behaviors/AddPixelEvent.py +++ b/behaviors/AddPixelEvent.py @@ -1,4 +1,26 @@ from operationscore.Behavior import * +import util.Strings as Strings +from logger import main_log class AddPixelEvent(Behavior): - def initBehavior(self): - className = self['Class'] + def behaviorInit(self): + [module, className] = self['Class'].split('.') + try: + exec('from ' + module+'.'+className + ' import *', globals()) + except Exception as inst: + main_log.error('Error importing ' + module+'.'+className+ '. Component not\ + initialized.') + main_log.error(str(inst)) + self.eventGenerator = eval('lambda args:'+className+'(args)') + + #^lambda function to do generate new event (takes args) + + def processResponse(self, sensors, recurses): + ret = [] + for sensory in sensors: + outDict = {} + outDict[Strings.LOCATION] = sensory[Strings.LOCATION] + settingsDict = dict(self.argDict) + settingsDict['Color'] = sensory['Color'] + outDict['PixelEvent'] = self.eventGenerator(settingsDict) + ret.append(outDict) + return (ret, recurses) diff --git a/behaviors/BehaviorChain.py b/behaviors/BehaviorChain.py index 0170fa8..39f4402 100644 --- a/behaviors/BehaviorChain.py +++ b/behaviors/BehaviorChain.py @@ -29,6 +29,11 @@ class BehaviorChain(Behavior): if hookRecurrence != []: main_log.warn('Hook recurrences are not currently supported. Implement it\ yourself or bug russell') - self.feedback[behaviorId] = recurrence - return response + self.feedback[behaviorId] = recurrence + return (response, []) + + def appendBehavior(behavior): + bid = compReg.registerComponent(behavior) #register behavior (will make + #a new id if there isn't one) + self['ChainedBehaviors'].append(bid) diff --git a/behaviors/ColorChangerBehavior.py b/behaviors/ColorChangerBehavior.py index e1827eb..2a8d974 100644 --- a/behaviors/ColorChangerBehavior.py +++ b/behaviors/ColorChangerBehavior.py @@ -11,4 +11,4 @@ class ColorChangerBehavior(Behavior): else: newDict['Color'] = color.randomColor() ret.append(newDict) - return (ret, recursiveInputs) + return (ret, []) diff --git a/behaviors/DebugBehavior.py b/behaviors/DebugBehavior.py index 9bf3ea8..34f4106 100644 --- a/behaviors/DebugBehavior.py +++ b/behaviors/DebugBehavior.py @@ -5,4 +5,4 @@ class DebugBehavior(Behavior): def processResponse(self, sensorInputs, recursiveInputs): if sensorInputs != []: main_log.debug('Sensor Inputs: ' + str(sensorInputs)) - return [] + return ([], []) diff --git a/behaviors/EchoBehavior.py b/behaviors/EchoBehavior.py index be0ed14..589c42b 100644 --- a/behaviors/EchoBehavior.py +++ b/behaviors/EchoBehavior.py @@ -9,4 +9,4 @@ class EchoBehavior(Behavior): outDict[Strings.LOCATION] = sensory[Strings.LOCATION] outDict['Color'] = (255,0,0) ret.append(outDict) - return ret + return (ret, []) diff --git a/behaviors/ModifyParam.py b/behaviors/ModifyParam.py index 3701013..f589e05 100644 --- a/behaviors/ModifyParam.py +++ b/behaviors/ModifyParam.py @@ -5,7 +5,7 @@ class ModifyParam(Behavior): def processResponse(self, sensorInputs, recursiveInputs): paramType = self['ParamType'] paramName = self['ParamName'] - paramOp = self['ParamOp'] + paramOp = str(self['ParamOp']) if paramType == 'Sensor': searchSet = sensorInputs elif paramType == 'Recurse': @@ -13,12 +13,10 @@ class ModifyParam(Behavior): else: raise Exception('Unknown Param Type') for behaviorInput in searchSet: - if paramName in behaviorInput: - try: + if paramName in behaviorInput: #TODO: copy -> modify instead of just + #copying 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': diff --git a/behaviors/MoveBehavior.py b/behaviors/MoveBehavior.py new file mode 100644 index 0000000..9ae98b9 --- /dev/null +++ b/behaviors/MoveBehavior.py @@ -0,0 +1,29 @@ +from operationscore.Behavior import * +import util.ComponentRegistry as compReg +import util.Geo as Geo +import util.Strings as Strings + +class MoveBehavior(Behavior): + def processResponse(self, sensorInputs, recursiveInputs): + print 'processing' + print sensorInputs + if recursiveInputs: + currRecLocs = recursiveInputs + else: + currRecLocs = [{'Location' : (5, 5)), 'Color' : [255, 255, 255]}] + + if sensorInputs: # if input exists, change location + ret = [] + for currRecLoc in currRecLocs: + currDict = dict(currRecLoc) + for sensorInput in sensorInputs: + currDict['Location'][0] += sensorInput['x'] * self['XStep'] + currDict['Location'][1] += sensorInput['y'] * self['YStep'] + #currDict['Color'] = sensorInput['color'] + ret.append(currDict) + #print ret + return (ret, ret) + + else: # if not, return current recursive location. + #print currRecLocs + return (currRecLocs, currRecLocs) diff --git a/behaviors/PixelDecay.xml b/behaviors/PixelDecay.xml index f9eee0d..c19a1a8 100644 --- a/behaviors/PixelDecay.xml +++ b/behaviors/PixelDecay.xml @@ -1,9 +1,9 @@ <Behavior> - <Class>behaviors.DecayBehavior</Class> + <Class>behaviors.AddPixelEvent</Class> <Args> + <Class>pixelevents.DecayEvent</Class> <DecayType>Exponential</DecayType> <Coefficient>.01</Coefficient> <z-index>0</z-index> - <RenderToScreen>False</RenderToScreen> </Args> </Behavior> diff --git a/behaviors/RandomWalk.py b/behaviors/RandomWalk.py index 8254430..fd6c2c8 100644 --- a/behaviors/RandomWalk.py +++ b/behaviors/RandomWalk.py @@ -1,5 +1,19 @@ from operationscore.Behavior import * import util.ComponentRegistry as compReg +import util.Geo as Geo +import util.Strings as Strings +import random +import pdb class RandomWalk(Behavior): def processResponse(self, sensors, recursives): + ret = [] + s = self['StepSize'] + for sensory in sensors: + step = [random.randint(-s,s), random.randint(-s,s)] + outdict = dict(sensory) + outdict[Strings.LOCATION] = Geo.addLocations(step, outdict[Strings.LOCATION]) + ret.append(outdict) + return (ret,recursives) + + diff --git a/behaviors/RecursiveDecay.py b/behaviors/RecursiveDecay.py index ee38bc4..218813d 100644 --- a/behaviors/RecursiveDecay.py +++ b/behaviors/RecursiveDecay.py @@ -1,4 +1,5 @@ from operationscore.Behavior import * +import pdb class RecursiveDecay(Behavior): def processResponse(self, sensorInputs, recursiveInputs): ret = [] @@ -9,4 +10,4 @@ class RecursiveDecay(Behavior): response['ResponsesLeft'] -= 1 if response['ResponsesLeft'] > 0: ret.append(response) - return (ret, recursiveInputs) #no direct ouput + return (ret, []) #no direct ouput diff --git a/behaviors/RedShift.xml b/behaviors/RedShift.xml new file mode 100644 index 0000000..a99e2ba --- /dev/null +++ b/behaviors/RedShift.xml @@ -0,0 +1,9 @@ +<Behavior> + <Class>behaviors.RestrictLocation</Class> + <Args> + <Action>(255,0,255)</Action> + <ParamName>Color</ParamName> + <LocationRestriction>{x}>100</LocationRestriction> + </Args> +</Behavior> + diff --git a/ResponseMover.py b/behaviors/ResponseMover.py index 718400d..e1faccb 100644 --- a/ResponseMover.py +++ b/behaviors/ResponseMover.py @@ -1,3 +1,4 @@ +import pdb from operationscore.Behavior import * import util.ComponentRegistry as compReg #ResponseMover is a scaffold for behaviors that spawn 'walkers' which act autonomously on input. @@ -6,7 +7,6 @@ class ResponseMover(Behavior): def processResponse(self, sensorInputs, recursiveInputs): newResponses = sensorInputs ret = [] - ret += newResponses for recurInput in recursiveInputs: outDict = dict(recurInput) ret.append(outDict) diff --git a/behaviors/RestrictLocation.py b/behaviors/RestrictLocation.py new file mode 100644 index 0000000..febc9ed --- /dev/null +++ b/behaviors/RestrictLocation.py @@ -0,0 +1,36 @@ +from operationscore.Behavior import * +import util.ComponentRegistry as compReg +from behaviors.ModifyParam import * +import util.Geo as Geo +import util.Strings as Strings +import random +import pdb +class RestrictLocation(Behavior): + def behaviorInit(self): + action = self['Action'] + modifyParamArgs = {'ParamType': 'Sensor', + 'ParamName':self['ParamName'],'ParamOp':self['Action']} + self.locBounds = self['LocationRestriction'] + self.paramModifier = ModifyParam(modifyParamArgs) + if isinstance(self.locBounds, str): + self.locBounds = self.locBounds.replace('{x}', 'l[0]') + self.locBounds = self.locBounds.replace('{y}', 'l[1]') + self.locEval = eval('lambda l:'+self.locBounds) + elif isinstance(self.locBounds, tuple): + if len(self.locBounds) != 4: + raise Exception('Must be in form (xmin,yin,xmax,ymax)') + else: + self.locEval = lambda l:Geo.pointWithinBoundingBox(l,\ + self.LocBounds) + def processResponse(self, sensorInputs, recursiveInputs): + ret = [] + for data in sensorInputs: + if not self.locEval(data['Location']): + (dataOut, recur) = self.paramModifier.immediateProcessInput([data], []) + #behaviors expect lists ^[] + ret += dataOut + else: + ret.append(data) + return (ret, []) + + diff --git a/behaviors/RunningBehavior.py b/behaviors/RunningBehavior.py index 92db69b..5eb33f7 100644 --- a/behaviors/RunningBehavior.py +++ b/behaviors/RunningBehavior.py @@ -15,6 +15,7 @@ class RunningBehavior(Behavior): outDict['StepSize'] = self['StepSize'] outDict['Location']= Geo.addLocations(outDict['Location'], (outDict['StepSize']*outDict['Dir'],0)) + if not Geo.pointWithinBoundingBox(outDict['Location'], \ compReg.getComponent('Screen').getSize()): outDict['Dir'] *= -1 diff --git a/behaviors/Square.py b/behaviors/Square.py new file mode 100644 index 0000000..a6e9401 --- /dev/null +++ b/behaviors/Square.py @@ -0,0 +1,11 @@ +from operationscore.Behavior import * +class Square(Behavior): + def processResponse(self, sensorInputs, recursiveInputs): + for sensory in sensorInputs:#TODO: consider replicating the dict + xLoc = sensory['Location'][0] + yLoc = sensory['Location'][1] + width = self['Width'] + sensory['Location'] =\ + '{x}<'+str(xLoc+width)+',{x}>'+str(xLoc-width)+\ + ',{y}<'+str(yLoc+width)+',{y}>'+str(yLoc-width) + return (sensorInputs, recursiveInputs) diff --git a/config/6thFloor.xml b/config/6thFloor.xml new file mode 100644 index 0000000..9c5f77e --- /dev/null +++ b/config/6thFloor.xml @@ -0,0 +1,208 @@ +<!---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><!--Passed as a dictionary--> + <Id>pygame</Id> + <RefreshInterval>10</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> + <InputElement> + <Class>inputs.RandomLocs</Class> + <Args> + <Id>randomLoc</Id> + </Args> + </InputElement> + </InputConfiguration> + <BehaviorConfiguration> + <Behavior> + <Class>behaviors.EchoBehavior</Class> + <Args> + <Id>echo</Id> + <z-index>0</z-index> + <RenderToScreen>False</RenderToScreen> + </Args> + </Behavior> + <Behavior Id="redshift"> + <InheritsFrom>behaviors/RedShift.xml</InheritsFrom> + </Behavior> + <Behavior Id="colorchange"> + <InheritsFrom>behaviors/RandomColor.xml</InheritsFrom> + </Behavior> + <Behavior Id="decay"> + <InheritsFrom>behaviors/PixelDecay.xml</InheritsFrom> + </Behavior> + <Behavior Id="slowdecay"> + <InheritsFrom>behaviors/PixelDecay.xml</InheritsFrom> + <Args> + <Coefficient>.01</Coefficient> + </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.AllPixelsLeft</Class> + <Args> + <Id>pixelsleft</Id> + </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>50</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> + <Mapper>gaussmap</Mapper> + </Args> + </Behavior> + <Behavior> + <Class>behaviors.BehaviorChain</Class> + <Args> + <Id>randomwalk</Id> + <Inputs> + <Id>pygame</Id> + </Inputs> + <ChainedBehaviors> + <Id>colorchange</Id> + <Id>mover</Id> + <Id>decay</Id> + </ChainedBehaviors> + <RecursiveHooks>{'mover':'redwalk'}</RecursiveHooks> + <RenderToScreen>True</RenderToScreen> + <Mapper>gaussmap</Mapper> + </Args> + </Behavior> + <Behavior> + <Class>behaviors.ResponseMover</Class> + <Args> + <Id>mover</Id> + </Args> + </Behavior> + <Behavior> + <Class>behaviors.BehaviorChain</Class> + <Args> + <Id>redwalk</Id> + <ChainedBehaviors> + <Id>randmovement</Id> + <Id>redshift</Id> + </ChainedBehaviors> + </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.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> + <Id>tcp</Id> + </Inputs> + <ChainedBehaviors> + <Id>echo</Id> + <Id>redshift</Id> + <Id>square</Id> + <Id>slowdecay</Id> + </ChainedBehaviors> + <RenderToScreen>True</RenderToScreen> + </Args> + </Behavior> + <Behavior Id="running"> + <InheritsFrom>behaviors/RunningBehavior.xml</InheritsFrom> + </Behavior> + </BehaviorConfiguration> +</LightInstallation> diff --git a/config/MobileTest.xml b/config/MobileTest.xml new file mode 100644 index 0000000..2f736ea --- /dev/null +++ b/config/MobileTest.xml @@ -0,0 +1,147 @@ +<!---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/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/SixStripUDP.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>100</RefreshInterval> + </Args> + </InputElement> + <InputElement Id="followmouse"> + <InheritsFrom>inputs/MouseFollower.xml</InheritsFrom> + </InputElement> + <InputElement> + <Class>inputs.RandomLocs</Class> + <Args> + <Id>randomLoc</Id> + </Args> + </InputElement> + <InputElement> + <Class>inputs.TCPInput</Class> + <Args> + <Id>TCP</Id> + <Port>20120</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> + </Args> + </Behavior> + <Behavior Id="colorchange"> + <InheritsFrom>behaviors/RandomColor.xml</InheritsFrom> + </Behavior> + <Behavior Id="decay"> + <InheritsFrom>behaviors/PixelDecay.xml</InheritsFrom> + </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.AllPixelsLeft</Class> + <Args> + <Id>pixelsleft</Id> + </Args> + </Behavior> + <Behavior Id="recursivedecay"> + <InheritsFrom>behaviors/LoopAndDie.xml</InheritsFrom> + <Args> + <InitialResponseCount>200</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> + <Mapper>gaussmap</Mapper> + </Args> + </Behavior> + <Behavior Id="accelerate"> + <InheritsFrom>behaviors/Accelerate.xml</InheritsFrom> + </Behavior> + <Behavior> + <Class>behaviors.BehaviorChain</Class> + <Args> + <Id>acceleratedie</Id> + <ChainedBehaviors> + <Id>accelerate</Id> + <Id>recursivedecay</Id> + </ChainedBehaviors> + </Args> + </Behavior> + <Behavior Id="running"> + <InheritsFrom>behaviors/RunningBehavior.xml</InheritsFrom> + </Behavior> + <Behavior> + <Class>behaviors.MoveBehavior</Class> + <Args> + <Id>move</Id> + <Inputs> + <Id>TCP</Id> + </Inputs> + <XStep>1</XStep> + <YStep>1</YStep> + <RenderToScreen>True</RenderToScreen> + </Args> + </Behavior> + </BehaviorConfiguration> +</LightInstallation> diff --git a/config/Outdoor.xml b/config/Outdoor.xml index 9ee0c3a..e137ec4 100644 --- a/config/Outdoor.xml +++ b/config/Outdoor.xml @@ -40,9 +40,17 @@ <Class>inputs.PygameInput</Class> <Args><!--Passed as a dictionary--> <Id>pygame</Id> - <RefreshInterval>100</RefreshInterval> + <RefreshInterval>10</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> @@ -62,12 +70,27 @@ <RenderToScreen>False</RenderToScreen> </Args> </Behavior> + <Behavior Id="redshift"> + <InheritsFrom>behaviors/RedShift.xml</InheritsFrom> + </Behavior> <Behavior Id="colorchange"> <InheritsFrom>behaviors/RandomColor.xml</InheritsFrom> + <Args> + <ColorList> + <Color>(0,255,0)</Color> + <Color>(255,0,0)</Color> + </ColorList> + </Args> </Behavior> <Behavior Id="decay"> <InheritsFrom>behaviors/PixelDecay.xml</InheritsFrom> </Behavior> + <Behavior Id="slowdecay"> + <InheritsFrom>behaviors/PixelDecay.xml</InheritsFrom> + <Args> + <Coefficient>.01</Coefficient> + </Args> + </Behavior> <Behavior> <Class>behaviors.DebugBehavior</Class> <Args> @@ -84,10 +107,17 @@ <Id>pixelsleft</Id> </Args> </Behavior> + <Behavior> + <Class>behaviors.Square</Class> + <Args> + <Id>square</Id> + <Width>5</Width> + </Args> + </Behavior> <Behavior Id="recursivedecay"> <InheritsFrom>behaviors/LoopAndDie.xml</InheritsFrom> <Args> - <InitialResponseCount>200</InitialResponseCount> + <InitialResponseCount>30</InitialResponseCount> </Args> </Behavior> <Behavior> @@ -96,7 +126,7 @@ <Id>runcolordecay</Id> <Inputs> <Id>pygame</Id> - <Id>randomLoc</Id> + <!--<Id>randomLoc</Id>--> </Inputs> <ChainedBehaviors> <Id>colorchange</Id> @@ -108,6 +138,46 @@ <Mapper>gaussmap</Mapper> </Args> </Behavior> + <Behavior> + <Class>behaviors.BehaviorChain</Class> + <Args> + <Id>randomwalk</Id> + <Inputs> + <Id>pygame</Id> + </Inputs> + <ChainedBehaviors> + <Id>colorchange</Id> + <Id>mover</Id> + <Id>decay</Id> + </ChainedBehaviors> + <RecursiveHooks>{'mover':'redwalk'}</RecursiveHooks> + <RenderToScreen>True</RenderToScreen> + <Mapper>gaussmap</Mapper> + </Args> + </Behavior> + <Behavior> + <Class>behaviors.ResponseMover</Class> + <Args> + <Id>mover</Id> + </Args> + </Behavior> + <Behavior> + <Class>behaviors.BehaviorChain</Class> + <Args> + <Id>redwalk</Id> + <ChainedBehaviors> + <Id>randmovement</Id> + <Id>redshift</Id> + </ChainedBehaviors> + </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> @@ -127,11 +197,13 @@ <Id>mousechaser</Id> <Inputs> <Id>followmouse</Id> + <Id>tcp</Id> </Inputs> <ChainedBehaviors> <Id>echo</Id> - <Id>pixelsleft</Id> - <Id>decay</Id> + <Id>redshift</Id> + <Id>square</Id> + <Id>slowdecay</Id> </ChainedBehaviors> <RenderToScreen>True</RenderToScreen> </Args> diff --git a/docs/designDocs.tex b/docs/designDocs.tex index 9b47d7d..8e62edc 100644 --- a/docs/designDocs.tex +++ b/docs/designDocs.tex @@ -35,6 +35,9 @@ between members as python dictionaries because their easy serialization. \end{itemize} + \section{Overview} + \begin{itemize} + \item \section{Operations Class Patterns} \classDoc{SmootCoreObject}{None}{All 2nd level classes (PixelAssembler, Renderer, Input, Behavior)} @@ -44,7 +47,8 @@ \item Defines a constructor that sets argDict \item Defines a \texttt{\_\_getitem\_\_} , which lets us acces items in argDict as if the class was a dictionary. - (\texttt{self['itemName']}) + (\texttt{self['itemName']}). It also automatically maps the + initial contents of the argDict to class attributes. \item Defines validateArgs and validateArgDict which validate the incoming arguments against a dictionary containing argument names as keys and an error message to diff --git a/inputs/TCPInput.py b/inputs/TCPInput.py index 197045f..e5475c1 100644 --- a/inputs/TCPInput.py +++ b/inputs/TCPInput.py @@ -1,7 +1,10 @@ import util.Strings as Strings +import pdb from operationscore.Input import * import socket, json, time import logging as main_log +import string + class TCPInput(Input): def inputInit(self): self.HOST = '' # Symbolic name meaning all available interfaces @@ -18,25 +21,35 @@ class TCPInput(Input): def sensingLoop(self): data = self.conn.recv(self.BUFFER_SIZE) main_log.debug('Incoming data', data) - if not data or 'end' in data: # data end, close socket + if not data or 'end' in data or data == '': # data end, close socket main_log.debug('End in data') + print 'end of stream' self.IS_RESPONDING = 0 + self.conn.close() self.sock.close() - if self.IS_RESPONDING == 1: # if 'responding', respond to the received data + if self.IS_RESPONDING == 1: # if 'responding', respond to the received data dataDict = json.loads(data) - # socketDict = {'data':dataDict, 'address':self.address} - socketDict = {Strings.LOCATION: (100 * (1 - dataDict['x'] / 10), 25 * (1 + dataDict['y'] / 10))} # like PygameInput - - self.respond(socketDict) + self.respond(dataDict) + + #try: + # for datagroup in data.split('\n'): + # if datagroup != None and datagroup != '': + # dataDict = json.loads(datagroup) + # self.respond(dataDict) + # socketDict = {'data':dataDict, 'address':self.address} + #socketDict = {Strings.LOCATION: (dataDict['x'], dataDict['y'])} # like PygameInput + #print 'input' + #self.respond(socketDict) + #except Exception as exp: + # print str(exp) else: # if not 'responding', don't respond to data and restart socket # * an incomplete hack for now. will be changed if same-type-multi-Input is implemented. - time.sleep(1) + + self.IS_RESPONDING = 1 self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 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() - self.IS_RESPONDING = 1 - diff --git a/layouts/60StripLayout.xml b/layouts/60StripLayout.xml new file mode 100644 index 0000000..30f51c5 --- /dev/null +++ b/layouts/60StripLayout.xml @@ -0,0 +1,182 @@ +<PixelConfiguration> + <PixelStrip Id="strip1.1" originLocation="(0,0)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip1.2" originLocation="(200,0)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip2.1" originLocation="(0,15)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip2.2" originLocation="(200,15)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip3.1" originLocation="(0,30)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip3.2" originLocation="(200,30)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip4.1" originLocation="(0,45)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip4.2" originLocation="(200,45)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip5.1" originLocation="(0,60)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip5.2" originLocation="(200,60)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip6.1" originLocation="(0,75)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip6.2" originLocation="(200,75)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip7.1" originLocation="(0,90)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip7.2" originLocation="(200,90)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip8.1" originLocation="(0,105)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip8.2" originLocation="(200,105)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip9.1" originLocation="(0,120)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip9.2" originLocation="(200,120)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip10.1" originLocation="(0,135)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip10.2" originLocation="(200,135)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip11.1" originLocation="(0,150)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip11.2" originLocation="(200,150)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip12.1" originLocation="(0,165)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip12.2" originLocation="(200,165)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip13.1" originLocation="(0,180)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip13.2" originLocation="(200,180)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip14.1" originLocation="(0,195)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip14.2" originLocation="(200,195)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip15.1" originLocation="(0,210)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip15.2" originLocation="(200,210)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip16.1" originLocation="(400,0)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip16.2" originLocation="(600,0)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip17.1" originLocation="(400,15)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip17.2" originLocation="(600,15)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip18.1" originLocation="(400,30)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip18.2" originLocation="(600,30)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip19.1" originLocation="(400,45)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip19.2" originLocation="(600,45)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip20.1" originLocation="(400,60)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip20.2" originLocation="(600,60)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip21.1" originLocation="(400,75)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip21.2" originLocation="(600,75)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip22.1" originLocation="(400,90)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip22.2" originLocation="(600,90)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip23.1" originLocation="(400,105)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip23.2" originLocation="(600,105)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip24.1" originLocation="(400,120)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip24.2" originLocation="(600,120)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip25.1" originLocation="(400,135)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip25.2" originLocation="(600,135)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip26.1" originLocation="(400,150)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip26.2" originLocation="(600,150)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip27.1" originLocation="(400,165)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip27.2" originLocation="(600,165)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip28.1" originLocation="(400,180)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip28.2" originLocation="(600,180)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip29.1" originLocation="(400,195)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip29.2" originLocation="(600,195)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip30.1" originLocation="(400,210)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> + <PixelStrip Id="strip30.2" originLocation="(600,210)"> + <InheritsFrom>layouts/50PixelStrip.xml</InheritsFrom> + </PixelStrip> +</PixelConfiguration> diff --git a/logger/loggingConfig.ini b/logger/loggingConfig.ini index 6727c26..ac760ce 100644 --- a/logger/loggingConfig.ini +++ b/logger/loggingConfig.ini @@ -18,7 +18,7 @@ level = INFO handlers = console [logger_smoot_light] -level = DEBUG +level = ERROR handlers = file qualname = smoot_light propagate = 0 diff --git a/operationscore/Behavior.py b/operationscore/Behavior.py index d48c1d5..882a290 100644 --- a/operationscore/Behavior.py +++ b/operationscore/Behavior.py @@ -22,21 +22,19 @@ class Behavior(SmootCoreObject): self.behaviorInit() def behaviorInit(self): pass + def addMapper(fn): + def withmap(fn): + return self.addMapperToResponse(fn()) + return withmap def processResponse(self, sensorInputs, recursiveInputs): - pass + raise Exception('ProcessResponse not defined!') def addInput(self, sensorInput): self.sensorResponseQueue.append(sensorInput) #used for behavior chaining def immediateProcessInput(self, sensorInputs, recursiveInputs=[]): - try: - (output,recursions) = self.processResponse(sensorInputs, \ + (outputs,recursions) = self.processResponse(sensorInputs, \ recursiveInputs) - if type(output) != type([]): - output = [output] - return self.addMapperToResponse((output, recursions)) #TODO: use a decorator for this? - except: #deal with behaviors that don't return a tuple. - responses = self.processResponse(sensorInputs, recursiveInputs) - return (self.processResponse(sensorInputs, recursiveInputs),[]) + return self.addMapperToResponse((outputs,recursions)) def addInputs(self, sensorInputs): if type(sensorInputs) == type([]): [self.addInput(sensorInput) for sensorInput in sensorInputs] @@ -54,19 +52,8 @@ class Behavior(SmootCoreObject): return responses return responses def timeStep(self): #TODO: type checking. clean this up - responses = self.processResponse(self.sensorResponseQueue, \ + (outputs, recursions) = self.processResponse(self.sensorResponseQueue, \ self.recursiveResponseQueue) - if type(responses) == type(tuple()) and len(responses) == 2: - (outputs, recursions) = responses - else: - outputs = responses - recursions = [] self.sensorResponseQueue = [] self.recursiveResponseQueue = recursions - if type(outputs) != type([]): - outputs = [outputs] - try: - return self.addMapperToResponse(outputs) #TODO: WTF is up with this? - except: - pass return self.addMapperToResponse(outputs) diff --git a/operationscore/PixelEvent.py b/operationscore/PixelEvent.py index 6b0812f..80d3b9e 100644 --- a/operationscore/PixelEvent.py +++ b/operationscore/PixelEvent.py @@ -2,6 +2,7 @@ #which should return a color, or None if the response is complete. Consider #requiring a generate event. from operationscore.SmootCoreObject import * +from pixelevents.StepEvent import * import util.ColorOps as color class PixelEvent(SmootCoreObject): def init(self): diff --git a/operationscore/PixelMapper.py b/operationscore/PixelMapper.py index e3f2515..1f94fa5 100644 --- a/operationscore/PixelMapper.py +++ b/operationscore/PixelMapper.py @@ -3,8 +3,14 @@ import pdb class PixelMapper(SmootCoreObject): def init(self): self.mem = {} #Dictionary of all seen events + self.totalCalls = 0 + self.cachehits = 0 def mapEvent(self, eventLocation, screen): + self.totalCalls += 1 + if self.totalCalls % 100 == 0: + print self['Id'], self.cachehits / float(self.totalCalls) if eventLocation in self.mem: + self.cachehits += 1 return self.mem[eventLocation] else: self.mem[eventLocation] = self.mappingFunction(eventLocation, screen) diff --git a/pixelcore/Pixel.py b/pixelcore/Pixel.py index b9fc07f..7260e56 100644 --- a/pixelcore/Pixel.py +++ b/pixelcore/Pixel.py @@ -29,10 +29,10 @@ class Pixel: #arg #Add a pixelEvent to the list of active events - def processInput(self,pixelEvent,zindex, currentTime=None): #consider migrating arg to dict + def processInput(self,pixelEvent,zindex, scale=1,currentTime=None): #consider migrating arg to dict if currentTime == None: currentTime = timeops.time() - self.events[currentTime] = (zindex, pixelEvent) + self.events[currentTime] = (zindex,scale, pixelEvent) def clearAllEvents(self): self.events = {} @@ -49,10 +49,10 @@ class Pixel: resultingColor = (0,0,0) colors = [] for eventTime in self.events: #TODO: right color weighting code - (zindex,event) = self.events[eventTime] + (zindex,scale,event) = self.events[eventTime] eventResult = event.state(currentTime-eventTime) if eventResult != None: - colors.append(eventResult) + colors.append(color.multiplyColor(eventResult,scale)) else: deadEvents.append(eventTime) diff --git a/pixelcore/PixelEventManager.py b/pixelcore/PixelEventManager.py new file mode 100644 index 0000000..779a0ce --- /dev/null +++ b/pixelcore/PixelEventManager.py @@ -0,0 +1,2 @@ +class PixelEventManager(object): + def init(self) diff --git a/pixelcore/Screen.py b/pixelcore/Screen.py index 22cfdb0..cfadee8 100644 --- a/pixelcore/Screen.py +++ b/pixelcore/Screen.py @@ -8,6 +8,7 @@ import util.Strings as Strings import util.TimeOps as timeops import itertools import sys +import pdb from logger import main_log #Class representing a collection of Pixels grouped into PixelStrips. Needs a #PixelMapper, currently set via setMapper by may be migrated into the argDict. @@ -37,9 +38,7 @@ class Screen: self.xSortedPixels.sort() self.xPixelLocs = [p[0] for p in self.xSortedPixels] - def render(self, surface): - [lS.render(surface) for lS in self.pixelStrips] - + #For debug only def allOn(self): [lS.allOn(-1) for lS in self.pixelStrips] @@ -74,6 +73,7 @@ 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 @@ -89,9 +89,7 @@ class Screen: #if type(mapper) != type(PixelMapper): # raise Exception('No default mapper specified.') pixelWeightList = mapper.mapEvent(responseInfo['Location'], self) - PixelEvent.addPixelEventIfMissing(responseInfo) currentTime = timeops.time() for (pixel, weight) in pixelWeightList: - pixel.processInput(responseInfo['PixelEvent'].scale(weight), 0, currentTime) #TODO: z-index - + pixel.processInput(responseInfo['PixelEvent'], 0,weight, currentTime) #TODO: z-index diff --git a/pixelevents/DecayEvent.py b/pixelevents/DecayEvent.py index 3767729..f8d5ef0 100644 --- a/pixelevents/DecayEvent.py +++ b/pixelevents/DecayEvent.py @@ -4,12 +4,12 @@ from util.ColorOps import * import util.Geo as Geo class DecayEvent(PixelEvent): def initEvent(self): - self.coefficient = float(abs(self['Coefficient'])) - if self['DecayType'] == 'Exponential': + self.coefficient = float(abs(self.Coefficient)) + if self.DecayType == 'Exponential': self.decayType = 1 else: self.decayType = 2 - self.color = self['Color'] + self.color = self.Color #SUBVERTING DESIGN FOR THE SAKE OF EFFICIENCY -- RUSSELL COHEN (2011-01-03-23:18) def state(self,timeDelay): diff --git a/pixelmappers/SimpleMapper.py b/pixelmappers/SimpleMapper.py index 2df24e0..19d44c4 100644 --- a/pixelmappers/SimpleMapper.py +++ b/pixelmappers/SimpleMapper.py @@ -13,7 +13,10 @@ class SimpleMapper(PixelMapper): if pixelDist < bestDist: bestPixel = pixel bestDist = pixelDist - return [(bestPixel,1)] + if bestPixel != None: + return [(bestPixel,1)] + else: + return [] else: #{x}>5,{y}<k #TODO: we should probably encapsulate this somewhere diff --git a/renderers/60StripSeq.xml b/renderers/60StripSeq.xml new file mode 100644 index 0000000..3f5255f --- /dev/null +++ b/renderers/60StripSeq.xml @@ -0,0 +1,130 @@ +<Renderer> + <Class>renderers.IndoorRenderer</Class> + <Args> + <Id>indoorRenderer</Id> + <PowerSupply> + <IP>10.32.0.0</IP> + <PortMapping>{'strip0.1':1, 'strip0.2':2}</PortMapping> + </PowerSupply> + <PowerSupply> + <IP>10.32.0.1</IP> + <PortMapping>{'strip1.1':1, 'strip1.2':2}</PortMapping> + </PowerSupply> + <PowerSupply> + <IP>10.32.0.2</IP> + <PortMapping>{'strip2.1':1, 'strip2.2':2}</PortMapping> + </PowerSupply> + <PowerSupply> + <IP>10.32.0.3</IP> + <PortMapping>{'strip3.1':1, 'strip3.2':2}</PortMapping> + </PowerSupply> + <PowerSupply> + <IP>10.32.0.4</IP> + <PortMapping>{'strip4.1':1, 'strip4.2':2}</PortMapping> + </PowerSupply> + <PowerSupply> + <IP>10.32.0.5</IP> + <PortMapping>{'strip5.1':1, 'strip5.2':2}</PortMapping> + </PowerSupply> + <PowerSupply> + <IP>10.32.0.6</IP> + <PortMapping>{'strip6.1':1, 'strip6.2':2}</PortMapping> + </PowerSupply> + <PowerSupply> + <IP>10.32.0.7</IP> + <PortMapping>{'strip7.1':1, 'strip7.2':2}</PortMapping> + </PowerSupply> + <PowerSupply> + <IP>10.32.0.8</IP> + <PortMapping>{'strip8.1':1, 'strip8.2':2}</PortMapping> + </PowerSupply> + <PowerSupply> + <IP>10.32.0.9</IP> + <PortMapping>{'strip9.1':1, 'strip9.2':2}</PortMapping> + </PowerSupply> + <PowerSupply> + <IP>10.32.0.10</IP> + <PortMapping>{'strip10.1':1, 'strip10.2':2}</PortMapping> + </PowerSupply> + <PowerSupply> + <IP>10.32.0.11</IP> + <PortMapping>{'strip11.1':1, 'strip11.2':2}</PortMapping> + </PowerSupply> + <PowerSupply> + <IP>10.32.0.12</IP> + <PortMapping>{'strip12.1':1, 'strip12.2':2}</PortMapping> + </PowerSupply> + <PowerSupply> + <IP>10.32.0.13</IP> + <PortMapping>{'strip13.1':1, 'strip13.2':2}</PortMapping> + </PowerSupply> + <PowerSupply> + <IP>10.32.0.14</IP> + <PortMapping>{'strip14.1':1, 'strip14.2':2}</PortMapping> + </PowerSupply> + <PowerSupply> + <IP>10.32.0.15</IP> + <PortMapping>{'strip15.1':1, 'strip15.2':2}</PortMapping> + </PowerSupply> + <PowerSupply> + <IP>10.32.0.16</IP> + <PortMapping>{'strip16.1':1, 'strip16.2':2}</PortMapping> + </PowerSupply> + <PowerSupply> + <IP>10.32.0.17</IP> + <PortMapping>{'strip17.1':1, 'strip17.2':2}</PortMapping> + </PowerSupply> + <PowerSupply> + <IP>10.32.0.18</IP> + <PortMapping>{'strip18.1':1, 'strip18.2':2}</PortMapping> + </PowerSupply> + <PowerSupply> + <IP>10.32.0.19</IP> + <PortMapping>{'strip19.1':1, 'strip19.2':2}</PortMapping> + </PowerSupply> + <PowerSupply> + <IP>10.32.0.20</IP> + <PortMapping>{'strip20.1':1, 'strip20.2':2}</PortMapping> + </PowerSupply> + <PowerSupply> + <IP>10.32.0.21</IP> + <PortMapping>{'strip21.1':1, 'strip21.2':2}</PortMapping> + </PowerSupply> + <PowerSupply> + <IP>10.32.0.22</IP> + <PortMapping>{'strip22.1':1, 'strip22.2':2}</PortMapping> + </PowerSupply> + <PowerSupply> + <IP>10.32.0.23</IP> + <PortMapping>{'strip23.1':1, 'strip23.2':2}</PortMapping> + </PowerSupply> + <PowerSupply> + <IP>10.32.0.24</IP> + <PortMapping>{'strip24.1':1, 'strip24.2':2}</PortMapping> + </PowerSupply> + <PowerSupply> + <IP>10.32.0.25</IP> + <PortMapping>{'strip25.1':1, 'strip25.2':2}</PortMapping> + </PowerSupply> + <PowerSupply> + <IP>10.32.0.26</IP> + <PortMapping>{'strip26.1':1, 'strip26.2':2}</PortMapping> + </PowerSupply> + <PowerSupply> + <IP>10.32.0.27</IP> + <PortMapping>{'strip27.1':1, 'strip27.2':2}</PortMapping> + </PowerSupply> + <PowerSupply> + <IP>10.32.0.28</IP> + <PortMapping>{'strip28.1':1, 'strip28.2':2}</PortMapping> + </PowerSupply> + <PowerSupply> + <IP>10.32.0.29</IP> + <PortMapping>{'strip29.1':1, 'strip29.2':2}</PortMapping> + </PowerSupply> + <PowerSupply> + <IP>10.32.0.30</IP> + <PortMapping>{'strip30.1':1, 'strip30.2':2}</PortMapping> + </PowerSupply> + </Args> +</Renderer> diff --git a/renderers/IndoorRenderer.py b/renderers/IndoorRenderer.py index 5f8546a..76ec172 100644 --- a/renderers/IndoorRenderer.py +++ b/renderers/IndoorRenderer.py @@ -21,7 +21,7 @@ class IndoorRenderer(Renderer): self.stripLocations[stripId] = (ip, \ stripsInPowerSupply[stripId]) def render(self, lightSystem, currentTime=timeops.time()): - try: + #try: for pixelStrip in lightSystem.pixelStrips: stripId = pixelStrip.argDict['Id'] (ip, port) = self.stripLocations[stripId] @@ -30,6 +30,6 @@ class IndoorRenderer(Renderer): self.sockets[ip] = network.getConnectedSocket(ip,sock_port) packet = composer.composePixelStripPacket(pixelStrip, port, currentTime) self.sockets[ip].send(packet, 0x00) - except Exception as inst: - print inst + #except Exception as inst: + # print inst diff --git a/renderers/PygameRenderer.py b/renderers/PygameRenderer.py index 24b2d08..9582a03 100644 --- a/renderers/PygameRenderer.py +++ b/renderers/PygameRenderer.py @@ -6,7 +6,7 @@ import pdb class PygameRenderer(Renderer): def initRenderer(self): pygame.init() - self.screen = pygame.display.set_mode((1300,50)) + self.screen = pygame.display.set_mode((1300,500)) self.background = pygame.Surface(self.screen.get_size()) self.background = self.background.convert() self.background.fill(Color('Black')) diff --git a/tests/TestComponentRegistry.py b/tests/TestComponentRegistry.py index 1acd0c8..5ada524 100644 --- a/tests/TestComponentRegistry.py +++ b/tests/TestComponentRegistry.py @@ -1,11 +1,19 @@ import unittest import util.ComponentRegistry as compReg +from operationscore.SmootCoreObject import SmootCoreObject class TestComponentRegistry(unittest.TestCase): def setUp(self): compReg.initRegistry() def tearDown(self): compReg.clearRegistry() - def test_register_component(self): - comp = SmootCoreObject({'Id': obj1}) + def test_register_component_id_specified(self): + comp = SmootCoreObject({'Id': 'obj1'}) compReg.registerComponent(comp) + newcomp = compReg.getComponent('obj1') + assert comp == newcomp + def test_register_new_id(self): + comp = SmootCoreObject({}) + cid =compReg.registerComponent(comp) + newcomp = compReg.getComponent(cid) + assert comp == newcomp diff --git a/util/ComponentRegistry.py b/util/ComponentRegistry.py index 0518f56..776cd17 100644 --- a/util/ComponentRegistry.py +++ b/util/ComponentRegistry.py @@ -4,14 +4,18 @@ from logger import main_log #TODO: make component registry a singleton def initRegistry(): #TODO: don't overwrite existing registry - globals()['Registry'] = {} + if not 'Registry' in globals(): + globals()['Registry'] = {} def clearRegistry(): initRegistry() + def removeComponent(cid): globals()['Registry'].pop(cid) + def getComponent(cid): return globals()['Registry'][cid] + #Registry of all components of the light system #TODO: pick a graceful failure behavior and implement it def registerComponent(component, cid=None): @@ -26,11 +30,16 @@ def registerComponent(component, cid=None): main_log.debug(cid + 'automatically assigned') globals()['Registry'][cid] = component return cid -#def registerDefault( + +def verifyUniqueId(cid): + return not cid in globals()['Registry'] + def removeComponent(cid): globals()['Registry'].pop(cid) + def getComponent(cid): return globals()['Registry'][cid] + def getNewId(): trialKey = len(globals()['Registry']) trialId = hashlib.md5(str(trialKey)).hexdigest() diff --git a/util/Config.py b/util/Config.py index 4c1eb1e..c2d8806 100644 --- a/util/Config.py +++ b/util/Config.py @@ -24,6 +24,7 @@ def loadConfigFile(fileName): #TODO: error handling etc. return config except Exception as inst: main_log.error('Error loading config file ' + fileName)#, inst) TODO: log exception too + main_log.error(str(inst)) return None #Takes an Element or an ElementTree. If it is a tree, it returns its root. Otherwise, just returns #it @@ -98,12 +99,19 @@ def fileToDict(fileName): def pullArgsFromItem(parentNode): attribArgs = {} for arg in parentNode.attrib: #automatically pull attributes into the argdict - attribArgs[arg] = parentNode.attrib[arg] + attribArgs[arg] = attemptEval(parentNode.attrib[arg]) argNode = parentNode.find('Args') args = generateArgDict(argNode) for key in attribArgs: args[key] = attribArgs[key] return args + +def attemptEval(val): + try: + val = eval(val) + except (NameError, SyntaxError): + val = str(val) + return val def generateArgDict(parentNode, recurse=False): args = {} for arg in parentNode.getchildren(): @@ -112,10 +120,7 @@ def generateArgDict(parentNode, recurse=False): value = generateArgDict(arg, True) else: #convert into python if possible, otherwise don't - try: - value = eval(arg.text) - except (NameError,SyntaxError): - value = str(arg.text) + value = attemptEval(arg.text) if key in args: #build of lists of like-elements if type(args[key]) != type([]): args[key] = [args[key]] diff --git a/util/PacketComposition.py b/util/PacketComposition.py index 3574170..c4fcdc3 100644 --- a/util/PacketComposition.py +++ b/util/PacketComposition.py @@ -1,14 +1,11 @@ import struct VERSION = 0x0001 MAGIC = 0x4adc0104 -MOREMAGIC = 0xdeadbeef -DEEPMAGIC = 0xc001d00d -MAGICHASH = 0x69000420 PORTOUT = 0x0108 UNI = 0 import pdb import util.TimeOps as timeops -kinetDict = {'flags': 0, 'startcode': 0, 'pad':0} +argDict = {'flags': 0, 'startcode': 0, 'pad':0} def composePixelStripData(pixelStrip,currentTime=timeops.time()): packet = bytearray() for light in pixelStrip: @@ -32,10 +29,10 @@ def memoize(f): @memoize def cachePacketHeader(port): packet = bytearray() - subDict = dict(kinetDict) - subDict['len'] = 38000 #I have no idea why this works. + subDict = dict(argDict) + subDict['len'] = 38500 #I have no idea why this works. subDict['port'] = port - packet.extend(kinetPortOutPacket(subDict)) + packet.extend(portOutPacket(subDict)) packet.append(0x0) return packet def composePixelStripPacket(pixelStrip,port, currentTime): @@ -43,18 +40,18 @@ def composePixelStripPacket(pixelStrip,port, currentTime): data = composePixelStripData(pixelStrip, currentTime) packet.extend(data) return packet -def kinetHeader(): +def packheader(): header = bytearray() header.extend(struct.pack('L', MAGIC)) header.extend(struct.pack('H', VERSION)) header.extend(struct.pack('H', PORTOUT)) header.extend(struct.pack('L', 0)) return header -def kinetPortOut(): - header = kinetHeader() +def portOut(): + header = packheader() header.extend(struct.pack('L', UNI)) return header -def kinetPortOutPayload(argDict): +def portOutPayload(argDict): payload = bytearray() payload.extend(struct.pack('B', argDict['port'])) payload.extend(struct.pack('H', argDict['flags'])) @@ -62,8 +59,8 @@ def kinetPortOutPayload(argDict): payload.extend(struct.pack('H', argDict['len'])) payload.extend(struct.pack('H', argDict['startcode'])) return payload -def kinetPortOutPacket(payloadArgs): +def portOutPacket(payloadArgs): packet = bytearray() - packet.extend(kinetPortOut()) - packet.extend(kinetPortOutPayload(payloadArgs)) + packet.extend(portOut()) + packet.extend(portOutPayload(payloadArgs)) return packet |