aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar eugue <eug.sun@gmail.com>2011-01-24 14:41:38 -0500
committerGravatar eugue <eug.sun@gmail.com>2011-01-24 14:41:38 -0500
commit00e836cfa4e2652d724972585d661143142af002 (patch)
treef612ea43024f13dc8c16f192735676e9976630fc
parentd39f871cf9fcce13c6db315052a4951f692719f9 (diff)
merge with biginstall
-rw-r--r--LightInstallation.py4
-rw-r--r--Profile.py2
-rw-r--r--TestAll.py4
-rw-r--r--behaviors/Accelerate.xml2
-rw-r--r--behaviors/AddPixelEvent.py26
-rw-r--r--behaviors/BehaviorChain.py9
-rw-r--r--behaviors/ColorChangerBehavior.py2
-rw-r--r--behaviors/DebugBehavior.py2
-rw-r--r--behaviors/EchoBehavior.py2
-rw-r--r--behaviors/ModifyParam.py8
-rw-r--r--behaviors/MoveBehavior.py29
-rw-r--r--behaviors/PixelDecay.xml4
-rw-r--r--behaviors/RandomWalk.py14
-rw-r--r--behaviors/RecursiveDecay.py3
-rw-r--r--behaviors/RedShift.xml9
-rw-r--r--behaviors/ResponseMover.py (renamed from ResponseMover.py)2
-rw-r--r--behaviors/RestrictLocation.py36
-rw-r--r--behaviors/RunningBehavior.py1
-rw-r--r--behaviors/Square.py11
-rw-r--r--config/6thFloor.xml208
-rw-r--r--config/MobileTest.xml147
-rw-r--r--config/Outdoor.xml82
-rw-r--r--docs/designDocs.tex6
-rw-r--r--inputs/TCPInput.py31
-rw-r--r--layouts/60StripLayout.xml182
-rw-r--r--logger/loggingConfig.ini2
-rw-r--r--operationscore/Behavior.py29
-rw-r--r--operationscore/PixelEvent.py1
-rw-r--r--operationscore/PixelMapper.py6
-rw-r--r--pixelcore/Pixel.py8
-rw-r--r--pixelcore/PixelEventManager.py2
-rw-r--r--pixelcore/Screen.py10
-rw-r--r--pixelevents/DecayEvent.py6
-rw-r--r--pixelmappers/SimpleMapper.py5
-rw-r--r--renderers/60StripSeq.xml130
-rw-r--r--renderers/IndoorRenderer.py6
-rw-r--r--renderers/PygameRenderer.py2
-rw-r--r--[-rwxr-xr-x]setup.sh0
-rw-r--r--tests/TestComponentRegistry.py12
-rw-r--r--util/ComponentRegistry.py13
-rw-r--r--util/Config.py15
-rw-r--r--util/PacketComposition.py25
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
diff --git a/Profile.py b/Profile.py
index 45ccc35..2f180c9 100644
--- a/Profile.py
+++ b/Profile.py
@@ -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")
diff --git a/TestAll.py b/TestAll.py
index 9921c7e..23b34ea 100644
--- a/TestAll.py
+++ b/TestAll.py
@@ -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/setup.sh b/setup.sh
index 8f5f6dc..8f5f6dc 100755..100644
--- a/setup.sh
+++ b/setup.sh
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