aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar rcoh <rcoh@mit.edu>2010-12-22 14:27:33 -0500
committerGravatar rcoh <rcoh@mit.edu>2010-12-22 14:27:33 -0500
commitc581408f028d5b8ceadc53c68d7c1252fbe09e6d (patch)
tree8724862d05bde3bb3427cdff378cdb08da8babd2
parenta1d9b85320c9b07d62470d78ef0c5f9015baf813 (diff)
About halfway done with support for pixel regions. Modified the component registry a bit. Added
support for multiple pixel mappers (and along with that, default components). RCOH
-rw-r--r--LightInstallation.py28
-rw-r--r--behaviors/BehaviorChain.py1
-rw-r--r--behaviors/DebugBehavior.py1
-rw-r--r--behaviors/DecayBehavior.py1
-rw-r--r--behaviors/EchoBehavior.py1
-rw-r--r--behaviors/ModifyParam.py1
-rw-r--r--behaviors/RunningBehavior.py1
-rw-r--r--config/Outdoor.xml9
-rw-r--r--inputs/PygameInput.py2
-rw-r--r--inputs/TCPInput.py1
-rw-r--r--inputs/TCPInput_backup.py1
-rw-r--r--inputs/UDPInput.py1
-rw-r--r--operationscore/Behavior.py21
-rw-r--r--operationscore/Input.py6
-rw-r--r--operationscore/PixelAssembler.py1
-rw-r--r--operationscore/PixelMapper.py1
-rw-r--r--operationscore/SmootCoreObject.py2
-rw-r--r--pixelcore/PixelStrip.py1
-rw-r--r--pixelcore/Screen.py14
-rw-r--r--pixelmappers/GaussianMapper.py1
-rw-r--r--pixelmappers/SimpleMapper.py4
-rw-r--r--renderers/IndoorRenderer.py19
-rw-r--r--util/ComponentRegistry.py36
-rw-r--r--util/Config.py4
-rw-r--r--util/NetworkOps.py6
-rw-r--r--util/PacketComposition.py2
-rw-r--r--util/Strings.py1
27 files changed, 103 insertions, 64 deletions
diff --git a/LightInstallation.py b/LightInstallation.py
index e6e5a26..48dee77 100644
--- a/LightInstallation.py
+++ b/LightInstallation.py
@@ -1,7 +1,7 @@
from xml.etree.ElementTree import ElementTree
from pixelcore.Screen import *
from pixelcore.PixelStrip import *
-import pdb, sys, time, Util, thread
+import pdb, sys, time, thread
from pygame.locals import *
import util.TimeOps as clock
import util.Config as configGetter
@@ -20,11 +20,8 @@ class LightInstallation:
self.componentDict = {}
self.inputBehaviorRegistry = {} #inputid -> behaviors listening to that
#input
- #give Util a pointer to our componentRegistry and screen so that everyone can use
- #it
- #Util.setComponentDict(self.componentDict)
self.screen = Screen()
- #Util.setScreen(self.screen)
+ compReg.initRegistry()
compReg.registerComponent(self.screen, 'Screen') #TODO: move to constants file
config = configGetter.loadConfigFile(configFileName)
#read configs from xml
@@ -33,25 +30,34 @@ class LightInstallation:
inputConfig = config.find('InputConfiguration')
behaviorConfig = config.find('BehaviorConfiguration')
mapperConfig = config.find('PixelMapperConfiguration')
+
+ installationConfig = config.find('InstallationConfiguration')
#inits
self.initializeScreen(pixelConfig)
self.initializeRenderers(rendererConfig)
self.initializeInputs(inputConfig)
self.initializeBehaviors(behaviorConfig)
self.initializeMapper(mapperConfig)
-
- self.screen.setMapper(self.mapper)
#registration in dict
self.registerComponents(self.renderers)
self.registerComponents(self.inputs)
self.registerComponents(self.behaviors)
+ self.registerComponents(self.mappers)
+ pdb.set_trace()
+ self.configureInstallation(installationConfig)
#Done initializing. Lets start this thing!
self.timer.stop()
print 'Initialization done. Time: ', self.timer.elapsed(), 'ms'
self.mainLoop()
+ def configureInstallation(self, installationConfig):
+ defaults = configGetter.generateArgDict(installationConfig.find('Defaults'))
+ for defaultSelection in defaults:
+ componentToMap = compReg.getComponent(defaults[defaultSelection])
+ compReg.registerComponent(compReg.getComponent(defaults[defaultSelection]),\
+ 'Default'+defaultSelection)
+
def initializeMapper(self, mapperConfig):
- self.mapper = self.initializeComponent(mapperConfig)[0] #TODO: support
- #multiple mappers
+ self.mappers = self.initializeComponent(mapperConfig)
def initializeScreen(self, layoutConfig):
pixelAssemblers = self.initializeComponent(layoutConfig)
[self.addPixelStrip(l) for l in pixelAssemblers]
@@ -72,7 +78,6 @@ class LightInstallation:
cid = component['Id']
if cid == None:
raise Exception('Components must have Ids!')
- #self.componentDict[cid] = component
compReg.registerComponent(component)
def initializeComponent(self, config):
components = []
@@ -141,7 +146,8 @@ class LightInstallation:
try:
[compReg.getComponent(b).addInput(responseDict) for b in boundBehaviorIds]
except:
- print 'Behaviors not initialized yet. WAIT!'
+ pass
+ #print 'Behaviors not initialized yet. WAIT!'
def main(argv):
print argv
if len(argv) == 1:
diff --git a/behaviors/BehaviorChain.py b/behaviors/BehaviorChain.py
index 65f5c9d..98585c9 100644
--- a/behaviors/BehaviorChain.py
+++ b/behaviors/BehaviorChain.py
@@ -1,6 +1,5 @@
from operationscore.Behavior import *
import util.ComponentRegistry as compReg
-import Util
import pdb
class BehaviorChain(Behavior):
def behaviorInit(self):
diff --git a/behaviors/DebugBehavior.py b/behaviors/DebugBehavior.py
index 4c8550a..a00346b 100644
--- a/behaviors/DebugBehavior.py
+++ b/behaviors/DebugBehavior.py
@@ -1,5 +1,4 @@
from operationscore.Behavior import *
-import Util
import pdb
class DebugBehavior(Behavior):
def processResponse(self, sensorInputs, recursiveInputs):
diff --git a/behaviors/DecayBehavior.py b/behaviors/DecayBehavior.py
index 56e1686..c1f6f92 100644
--- a/behaviors/DecayBehavior.py
+++ b/behaviors/DecayBehavior.py
@@ -1,7 +1,6 @@
from operationscore.Behavior import *
from pixelevents.DecayEvent import *
import util.Strings as Strings
-import Util
import pdb
class DecayBehavior(Behavior):
def processResponse(self, sensorInputs, recursiveInputs):
diff --git a/behaviors/EchoBehavior.py b/behaviors/EchoBehavior.py
index 002f8fb..be0ed14 100644
--- a/behaviors/EchoBehavior.py
+++ b/behaviors/EchoBehavior.py
@@ -1,6 +1,5 @@
from operationscore.Behavior import *
import util.Strings as Strings
-import Util
import pdb
class EchoBehavior(Behavior):
def processResponse(self, sensorInputs, recursiveInputs):
diff --git a/behaviors/ModifyParam.py b/behaviors/ModifyParam.py
index 38b8cd5..3701013 100644
--- a/behaviors/ModifyParam.py
+++ b/behaviors/ModifyParam.py
@@ -1,5 +1,4 @@
from operationscore.Behavior import *
-import Util
import pdb
#Class to perform a given operation on some element of an argDict. Designed to be used a recursive hook, but can serve sensor-based functions as well. Specify ParamType (Sensor or Recurse), ParamName, and ParamOp, (a valid python statement with the old value represented as {val})
class ModifyParam(Behavior):
diff --git a/behaviors/RunningBehavior.py b/behaviors/RunningBehavior.py
index 1969162..92db69b 100644
--- a/behaviors/RunningBehavior.py
+++ b/behaviors/RunningBehavior.py
@@ -2,7 +2,6 @@ from operationscore.Behavior import *
import util.ComponentRegistry as compReg
import util.Geo as Geo
import pdb
-import Util
class RunningBehavior(Behavior):
def processResponse(self, sensorInputs, recursiveInputs):
newResponses = sensorInputs
diff --git a/config/Outdoor.xml b/config/Outdoor.xml
index 10274b2..a004c4e 100644
--- a/config/Outdoor.xml
+++ b/config/Outdoor.xml
@@ -1,5 +1,10 @@
<!---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>
<PixelStrip>
<Class>layouts.LineLayout</Class>
@@ -62,15 +67,13 @@
</Args>
</PixelStrip>
</PixelConfiguration>
- <!--<PixelMapperConfiguration>
+ <PixelMapperConfiguration>
<PixelMapper>
<Class>pixelmappers.SimpleMapper</Class>
<Args>
<Id>simplemap</Id>
</Args>
</PixelMapper>
- </PixelMapperConfiguration>-->
- <PixelMapperConfiguration>
<PixelMapper>
<Class>pixelmappers.GaussianMapper</Class>
<Args>
diff --git a/inputs/PygameInput.py b/inputs/PygameInput.py
index f69d0f5..6779a20 100644
--- a/inputs/PygameInput.py
+++ b/inputs/PygameInput.py
@@ -1,4 +1,4 @@
-import time, Util
+import time
import util.Strings as Strings
from operationscore.Input import *
import pygame
diff --git a/inputs/TCPInput.py b/inputs/TCPInput.py
index 9f62825..1517afa 100644
--- a/inputs/TCPInput.py
+++ b/inputs/TCPInput.py
@@ -1,4 +1,3 @@
-import Util
import util.Strings as Strings
from operationscore.Input import *
import socket, json, time
diff --git a/inputs/TCPInput_backup.py b/inputs/TCPInput_backup.py
index 01b6a99..d2c4087 100644
--- a/inputs/TCPInput_backup.py
+++ b/inputs/TCPInput_backup.py
@@ -1,5 +1,4 @@
import SocketServer
-import Util
from operationscore.Input import *
"""
diff --git a/inputs/UDPInput.py b/inputs/UDPInput.py
index 5b83792..7d5609e 100644
--- a/inputs/UDPInput.py
+++ b/inputs/UDPInput.py
@@ -1,4 +1,3 @@
-import Util
from operationscore.Input import *
import socket
class UDPInput(Input):
diff --git a/operationscore/Behavior.py b/operationscore/Behavior.py
index 3bdf1ec..d48c1d5 100644
--- a/operationscore/Behavior.py
+++ b/operationscore/Behavior.py
@@ -33,14 +33,26 @@ class Behavior(SmootCoreObject):
recursiveInputs)
if type(output) != type([]):
output = [output]
- return (output, recursions)
- except:
+ 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),[])
def addInputs(self, sensorInputs):
if type(sensorInputs) == type([]):
[self.addInput(sensorInput) for sensorInput in sensorInputs]
else:
self.addInput(sensorInputs)
+ #private
+ def addMapperToResponse(self, responses):
+ if self['Mapper'] != None:
+ if type(responses) == type(tuple):
+ (out, recurs) = responses
+ return (self.addMapperToResponse(out), self.addMapperToResponse(recurs))
+ if type(responses) == type([]):
+ for r in responses:
+ r['Mapper'] = self['Mapper']
+ return responses
+ return responses
def timeStep(self): #TODO: type checking. clean this up
responses = self.processResponse(self.sensorResponseQueue, \
self.recursiveResponseQueue)
@@ -54,8 +66,7 @@ class Behavior(SmootCoreObject):
if type(outputs) != type([]):
outputs = [outputs]
try:
- return outputs
+ return self.addMapperToResponse(outputs) #TODO: WTF is up with this?
except:
pass
- #pdb.set_trace()
- return outputs
+ return self.addMapperToResponse(outputs)
diff --git a/operationscore/Input.py b/operationscore/Input.py
index 2144678..62c4682 100644
--- a/operationscore/Input.py
+++ b/operationscore/Input.py
@@ -1,4 +1,4 @@
-import threading,time,Util
+import threading,time
from operationscore.SmootCoreObject import *
#Abstract class for inputs. Inheriting classes should call "respond" to raise
#their event. Inheriting classes MUST define sensingLoop. Called at the
@@ -22,14 +22,10 @@ class Input(SmootCoreObject):
self.daemon = True #This kills this thread when the main thread stops
def respond(self, eventDict):
#if eventDict != []:
- #pdb.set_trace()
self.parentScope.lock.acquire()
self.parentScope.processResponse(self.argDict, eventDict)
self.parentScope.lock.release()
time.sleep(.001)
- def newEvent(self, event): #Mostly just useful for grabbing events from the
- #computer running the sim (key presses, clicks etc.)
- self.eventQueue.append(event)
def parentAlive(self):
try:
parentAlive = self.parentScope.alive()
diff --git a/operationscore/PixelAssembler.py b/operationscore/PixelAssembler.py
index c8563fb..6878f8a 100644
--- a/operationscore/PixelAssembler.py
+++ b/operationscore/PixelAssembler.py
@@ -1,6 +1,5 @@
from operationscore.SmootCoreObject import *
import util.Geo as Geo
-import Util
import pdb
class PixelAssembler(SmootCoreObject):
def init(self):
diff --git a/operationscore/PixelMapper.py b/operationscore/PixelMapper.py
index bbbfcf4..e3f2515 100644
--- a/operationscore/PixelMapper.py
+++ b/operationscore/PixelMapper.py
@@ -1,5 +1,4 @@
from operationscore.SmootCoreObject import *
-import Util
import pdb
class PixelMapper(SmootCoreObject):
def init(self):
diff --git a/operationscore/SmootCoreObject.py b/operationscore/SmootCoreObject.py
index 10df299..9784aab 100644
--- a/operationscore/SmootCoreObject.py
+++ b/operationscore/SmootCoreObject.py
@@ -1,4 +1,3 @@
-import Util
import pdb
import threading
import thread
@@ -8,6 +7,7 @@ class SmootCoreObject(threading.Thread):
self.argDict = argDict
self.validateArgs(self.className()+'.params')
self.lock = thread.allocate_lock()
+ threading.Thread.__init__(self)
self.init() #call init of inheriting class
# self.__setitem__ = self.argDict.__setitem__
# self.__getitem__ = self.argDict.__getitem__
diff --git a/pixelcore/PixelStrip.py b/pixelcore/PixelStrip.py
index cfab948..fceff8e 100644
--- a/pixelcore/PixelStrip.py
+++ b/pixelcore/PixelStrip.py
@@ -4,7 +4,6 @@ import util.Geo as Geo
from pixelevents.StepEvent import *
import pygame
import math
-import Util
import pdb
#Python class representing a single Pixel strip (usually 50 Pixels)
class PixelStrip:
diff --git a/pixelcore/Screen.py b/pixelcore/Screen.py
index a20cc72..da03ad2 100644
--- a/pixelcore/Screen.py
+++ b/pixelcore/Screen.py
@@ -1,7 +1,10 @@
from pixelcore.Pixel import *
from pixelcore.PixelStrip import *
from operationscore.PixelEvent import *
+from operationscore.PixelMapper import *
import util.Search as Search
+import util.ComponentRegistry as compReg
+import util.Strings as Strings
import itertools
#Class representing a collection of Pixels grouped into PixelStrips. Needs a
#PixelMapper, currently set via setMapper by may be migrated into the argDict.
@@ -29,8 +32,6 @@ class Screen:
self.xPixelLocs = [p[0] for p in self.xSortedPixels]
def render(self, surface):
[lS.render(surface) for lS in self.pixelStrips]
- def setMapper(self, mapper):
- self.mapper = mapper
def allOn(self):
[lS.allOn(-1) for lS in self.pixelStrips]
def __iter__(self): #the iterator of all our pixel strips chained togther
@@ -70,8 +71,13 @@ class Screen:
#[strip.respond(dict(responseInfo)) for strip in self.pixelStrips]
if type(responseInfo) != type(dict()):
pass
- #pdb.set_trace()
- pixelWeightList = self.mapper.mapEvent(responseInfo['Location'], self)
+ if 'Mapper' in responseInfo:
+ mapper = compReg.getComponent(responseInfo['Mapper'])
+ else:
+ mapper = compReg.getComponent(Strings.DEFAULT_MAPPER)
+ #if type(mapper) != type(PixelMapper):
+ # raise Exception('No default mapper specified.')
+ pixelWeightList = mapper.mapEvent(responseInfo['Location'], self)
PixelEvent.addPixelEventIfMissing(responseInfo)
for (pixel, weight) in pixelWeightList:
pixel.processInput(responseInfo['PixelEvent'].scale(weight), 0) #TODO: z-index
diff --git a/pixelmappers/GaussianMapper.py b/pixelmappers/GaussianMapper.py
index e94235e..8755acf 100644
--- a/pixelmappers/GaussianMapper.py
+++ b/pixelmappers/GaussianMapper.py
@@ -1,6 +1,5 @@
from operationscore.PixelMapper import *
import util.Geo as Geo
-import Util
class GaussianMapper(PixelMapper):
def mappingFunction(self, eventLocation, screen):
returnPixels = [] #TODO: consider preallocation and trimming
diff --git a/pixelmappers/SimpleMapper.py b/pixelmappers/SimpleMapper.py
index fdcf8b9..6b414ea 100644
--- a/pixelmappers/SimpleMapper.py
+++ b/pixelmappers/SimpleMapper.py
@@ -1,12 +1,12 @@
from operationscore.PixelMapper import *
-import Util
+import util.Geo as Geo
class SimpleMapper(PixelMapper):
def mappingFunction(self, eventLocation, screen):
if type(eventLocation) == type(tuple()):
bestDist = 10**10 #don't kill me, I'm lazy
bestPixel = None
for pixel in screen:
- pixelDist = Util.dist(pixel.location, eventLocation)
+ pixelDist = Geo.dist(pixel.location, eventLocation)
if pixelDist < bestDist:
bestPixel = pixel
bestDist = pixelDist
diff --git a/renderers/IndoorRenderer.py b/renderers/IndoorRenderer.py
index 2eac162..c13d11f 100644
--- a/renderers/IndoorRenderer.py
+++ b/renderers/IndoorRenderer.py
@@ -20,12 +20,15 @@ class IndoorRenderer(Renderer):
self.stripLocations[stripId] = (ip, \
stripsInPowerSupply[stripId])
def render(self, lightSystem):
- for pixelStrip in lightSystem.pixelStrips:
- stripId = pixelStrip.argDict['Id']
- (ip, port) = self.stripLocations[stripId]
- if not ip in self.sockets: #do we have a socket to this
- #strip? if not, spin off a new one
- self.sockets[ip] = network.getConnectedSocket(ip,port)
- packet = composer.composePixelStripPacket(pixelStrip, port)
- self.sockets[ip].send(packet, 0x00)
+ try:
+ for pixelStrip in lightSystem.pixelStrips:
+ stripId = pixelStrip.argDict['Id']
+ (ip, port) = self.stripLocations[stripId]
+ if not ip in self.sockets: #do we have a socket to this
+ #strip? if not, spin off a new one
+ self.sockets[ip] = network.getConnectedSocket(ip,port)
+ packet = composer.composePixelStripPacket(pixelStrip, port)
+ self.sockets[ip].send(packet, 0x00)
+ except:
+ pass #Rendering error. Log it. LOG
diff --git a/util/ComponentRegistry.py b/util/ComponentRegistry.py
index f8fe00d..119ce18 100644
--- a/util/ComponentRegistry.py
+++ b/util/ComponentRegistry.py
@@ -1,17 +1,43 @@
import pdb
+#component registry, a singleton
+import thread
+#class ComponentRegistry:
+# def __init__(self):
+# self.regDict = {}
+# @staticmethod
+# def getRegistry(self):
+# if self.instance == None:
+# self.instance = self.__class__()
+# return self.instance
+# def registerComponent(component, cid=None):
+# if cid != None:
+# globals()['Registry'][cid] = component
+# else:
+# try:
+# cid = component['Id']
+# globals()['Registry'][cid] = component
+# except:
+# raise Exception('Must specify Id, component did not store it')
+#def registerDefault(
+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
-registry = {}
+def initRegistry():
+ globals()['Registry'] = {}
def registerComponent(component, cid=None):
if cid != None:
- registry[cid] = component
+ globals()['Registry'][cid] = component
else:
try:
cid = component['Id']
- registry[cid] = component
+ globals()['Registry'][cid] = component
except:
raise Exception('Must specify Id, component did not store it')
+#def registerDefault(
def removeComponent(cid):
- registry.pop(cid)
+ globals()['Registry'].pop(cid)
def getComponent(cid):
- return registry[cid]
+ return globals()['Registry'][cid]
diff --git a/util/Config.py b/util/Config.py
index 4cf2ed5..f80b7b2 100644
--- a/util/Config.py
+++ b/util/Config.py
@@ -6,7 +6,7 @@ def loadParamRequirementDict(className):
classArgsMem[className] = fileToDict(CONFIG_PATH + className)
return classArgsMem[className]
def loadConfigFile(fileName): #TODO: error handling etc.
- try:
+ #try:
fileName = CONFIG_PATH + fileName
if '.params' in fileName:
return fileToDict(fileName)
@@ -14,7 +14,7 @@ def loadConfigFile(fileName): #TODO: error handling etc.
config = ElementTree()
config.parse(fileName)
return config
- except:
+ #except:
return None
def fileToDict(fileName):
fileText = ''
diff --git a/util/NetworkOps.py b/util/NetworkOps.py
index a247090..0404975 100644
--- a/util/NetworkOps.py
+++ b/util/NetworkOps.py
@@ -1,6 +1,8 @@
import socket
def getConnectedSocket(ip,port):
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- print (ip, port)
- sock.connect((ip, port))
+ try:
+ sock.connect((ip, port))
+ except:
+ print 'network down'
return sock
diff --git a/util/PacketComposition.py b/util/PacketComposition.py
index 5133459..2563c61 100644
--- a/util/PacketComposition.py
+++ b/util/PacketComposition.py
@@ -26,7 +26,6 @@ def composePixelStripPacket(pixelStrip,port):
subDict = dict(kinetDict)
subDict['len'] = 38000 #I have no idea why this works.
subDict['port'] = port
- #pdb.set_trace()
packet.extend(kinetPortOutPacket(subDict))
packet.append(0x0)
packet.extend(data)
@@ -50,7 +49,6 @@ def kinetPortOutPayload(argDict):
#payload.append(0x00) #somepadding? lolwtf.
payload.extend(struct.pack('H', argDict['len']))
payload.extend(struct.pack('H', argDict['startcode']))
- #pdb.set_trace()
return payload
def kinetPortOutPacket(payloadArgs):
packet = bytearray()
diff --git a/util/Strings.py b/util/Strings.py
index 1331db4..81c34f2 100644
--- a/util/Strings.py
+++ b/util/Strings.py
@@ -1 +1,2 @@
LOCATION = 'Location'
+DEFAULT_MAPPER = 'DefaultPixelMapper'