aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--LightInstallation.py11
-rw-r--r--TestProfile.py36
-rw-r--r--behaviors/AllPixelsLeft.py2
-rw-r--r--behaviors/BehaviorChain.py6
-rw-r--r--behaviors/DebugBehavior.py2
-rw-r--r--config/Outdoor.xml2
-rw-r--r--docs/designDocs.tex9
-rw-r--r--pixelevents/DecayEvent.py3
-rw-r--r--pixelevents/SingleFrameEvent.py8
-rw-r--r--pixelmappers/SimpleMapper.py14
-rw-r--r--tests/TestComponentRegistry.py11
-rw-r--r--util/ComponentRegistry.py47
-rw-r--r--util/Geo.py6
-rw-r--r--util/PacketComposition.py15
14 files changed, 112 insertions, 60 deletions
diff --git a/LightInstallation.py b/LightInstallation.py
index 6e3c093..aaedcf2 100644
--- a/LightInstallation.py
+++ b/LightInstallation.py
@@ -101,27 +101,26 @@ class LightInstallation:
except Exception as inst:
main_log.error('Error importing ' + module+'.'+'.className. Component not\
initialized.')
- main_log.error(str(inst)) #TODO: exception logging
- continue #TODO: verify functions as expected
+ main_log.error(str(inst))
+ continue
args = configGetter.pullArgsFromItem(configItem)
args['parentScope'] = self #TODO: we shouldn't give away scope
#like this, find another way.
try:
- components.append(eval(className+'(args)')) #TODO: doesn't error
+ components.append(eval(className+'(args)'))
main_log.debug(className + 'initialized with args ' + str(args))
#right
except Exception as inst:
main_log.error('Failure while initializing ' + className + ' with ' + str(args))
- main_log.error(str(inst)) #TODO: exception logging
+ main_log.error(str(inst))
return components
def alive(self):
return True
def mainLoop(self):
- #self.screen.allOn()
lastLoopTime = clock.time()
refreshInterval = 30
- runCount = 2000
+ runCount = 200
while runCount > 0:
runCount -= 1
loopStart = clock.time()
diff --git a/TestProfile.py b/TestProfile.py
index 342def6..663e57b 100644
--- a/TestProfile.py
+++ b/TestProfile.py
@@ -1,8 +1,9 @@
-#import cProfile
+import cProfile
import struct
import random
+import math
#from LightInstallation import main
-numiter = 10000000
+numiter = 1000000
def main1():
for i in xrange(0,numiter):
if 'abc' == 'def':
@@ -37,14 +38,27 @@ def dictlookup():
lookup[i] = struct.pack('B', random.randint(0,255))
for i in xrange(0,numiter):
b = lookup[random.randint(0,255)]
-print('starting')
-abc1()
-print('starting')
-abc2()
-print('done')
-#command = """abc1()"""
-#cProfile.runctx(command, globals(), locals())
+def dist1():
+ l1 = [21.43, 5423.123]
+ l2 = [123, 12312345]
+ for i in xrange(0,numiter):
+ d = math.sqrt(sum([(l1[i]-l2[i])**2 for i in range(len(l1))]))
+def dist2():
+ l1 = [21.43, 5423.123]
+ l2 = [123, 12312345]
+ for i in xrange(0,numiter):
+ d = math.sqrt((l1[0]-l2[0])**2+(l1[1]-l2[1])**2)
+def exptest():
+ for i in xrange(0, numiter):
+ a = math.exp(-1)
+ print a
+def expapprox():
+ for i in xrange(0, numiter):
+ a = 1+-1+(-1)**2/float(2)
+ print a
+command = """exptest()"""
+cProfile.runctx(command, globals(), locals())
-#command = """abc2()"""
-#cProfile.runctx(command, globals(), locals())
+command = """expapprox()"""
+cProfile.runctx(command, globals(), locals())
diff --git a/behaviors/AllPixelsLeft.py b/behaviors/AllPixelsLeft.py
index e1f4080..b48bfc1 100644
--- a/behaviors/AllPixelsLeft.py
+++ b/behaviors/AllPixelsLeft.py
@@ -5,5 +5,5 @@ class AllPixelsLeft(Behavior):
def processResponse(self, sensorInputs, recursiveInputs):
for sensory in sensorInputs:
xLoc = sensory['Location'][0]
- sensory['Location'] = '[{x}<' + str(xLoc) + ']'
+ sensory['Location'] = '{x}<' + str(xLoc)
return (sensorInputs, recursiveInputs)
diff --git a/behaviors/BehaviorChain.py b/behaviors/BehaviorChain.py
index ce161f9..0170fa8 100644
--- a/behaviors/BehaviorChain.py
+++ b/behaviors/BehaviorChain.py
@@ -1,6 +1,6 @@
from operationscore.Behavior import *
import util.ComponentRegistry as compReg
-import logging as main_log
+from logger import main_log
import pdb
class BehaviorChain(Behavior):
def behaviorInit(self):
@@ -8,6 +8,7 @@ class BehaviorChain(Behavior):
self.hooks = self['RecursiveHooks']
if self.hooks == None:
self.hooks = {}
+
def processResponse(self, sensorInputs, recursiveInputs):
response = sensorInputs
for behaviorId in self['ChainedBehaviors']:
@@ -27,6 +28,7 @@ class BehaviorChain(Behavior):
[])
if hookRecurrence != []:
main_log.warn('Hook recurrences are not currently supported. Implement it\
- yourself or bug russell')
+yourself or bug russell')
self.feedback[behaviorId] = recurrence
return response
+
diff --git a/behaviors/DebugBehavior.py b/behaviors/DebugBehavior.py
index 8e9bbdb..eb525e7 100644
--- a/behaviors/DebugBehavior.py
+++ b/behaviors/DebugBehavior.py
@@ -4,5 +4,5 @@ import pdb
class DebugBehavior(Behavior):
def processResponse(self, sensorInputs, recursiveInputs):
if sensorInputs != []:
- main_log.debug('Sensor Inputs: ', str(sensorInputs))
+ main_log.debug('Sensor Inputs: '+ str(sensorInputs))
return []
diff --git a/config/Outdoor.xml b/config/Outdoor.xml
index c2a2c3c..f0995b1 100644
--- a/config/Outdoor.xml
+++ b/config/Outdoor.xml
@@ -133,7 +133,7 @@
<Id>pixelsleft</Id>
<Id>decay</Id>
</ChainedBehaviors>
- <RenderToScreen>False</RenderToScreen>
+ <RenderToScreen>True</RenderToScreen>
</Args>
</Behavior>
<Behavior Id="running">
diff --git a/docs/designDocs.tex b/docs/designDocs.tex
index 0690d3f..9b47d7d 100644
--- a/docs/designDocs.tex
+++ b/docs/designDocs.tex
@@ -162,10 +162,10 @@ argument. This will be passed in via recursive inputs.}
\item Constants: \texttt{ALL\_CAPS\_WITH\_UNDERSCORES}
\end{itemize}
\subsection{Time}
- For time, use the \texttt{Util.time()} method to return the current
+ For time, use the \texttt{util.TimeOps.time()} method to return the current
time in ms.
\subsection{Acessing a Component Given an Id}
- Use \texttt{Util.getComponentById(id)}. This provides any
+ Use \texttt{util.ComponentRegistry.getComponent(id)}. This provides any
component access to any other components. We may consider a way to
make this read-only.
\subsection{Acessing Pixels}
@@ -174,7 +174,7 @@ argument. This will be passed in via recursive inputs.}
acceptable method.
\subsection{Determining the state of a \texttt{Pixel}}
The best practice for determining the color of a \texttt{Pixel} is to call
- \texttt{lightState} (may be renamed to State TODO). This ensures
+ \texttt{state}. This ensures
all current active responses running on the Pixel contribute correctly.
\subsection{Color}
For color, use a tuple of (R,G,B) 0-255 for each. Colors can be
@@ -182,4 +182,7 @@ argument. This will be passed in via recursive inputs.}
\subsection{Locations}
Locations are stored (x,y), in whatever unit you light system is
in. (Whatever unit you use when you define spacing).
+ \subsection{Constant Strings (key strings, 'Location', 'Color', etc.)}
+ Use the util.Strings module. It contains many currently in use
+ Strings, and ensures consistency.
\end{document}
diff --git a/pixelevents/DecayEvent.py b/pixelevents/DecayEvent.py
index c1166d6..3767729 100644
--- a/pixelevents/DecayEvent.py
+++ b/pixelevents/DecayEvent.py
@@ -1,6 +1,7 @@
from operationscore.PixelEvent import *
import math
from util.ColorOps import *
+import util.Geo as Geo
class DecayEvent(PixelEvent):
def initEvent(self):
self.coefficient = float(abs(self['Coefficient']))
@@ -13,7 +14,7 @@ class DecayEvent(PixelEvent):
#SUBVERTING DESIGN FOR THE SAKE OF EFFICIENCY -- RUSSELL COHEN (2011-01-03-23:18)
def state(self,timeDelay):
if self.decayType == 1:
- decay = math.exp(timeDelay*-1*self.coefficient)
+ decay = Geo.approxexp(timeDelay*-1*self.coefficient)
if self.decayType == 2:
decay = self.coefficient / timeDelay
color = multiplyColor(self.color, decay)
diff --git a/pixelevents/SingleFrameEvent.py b/pixelevents/SingleFrameEvent.py
new file mode 100644
index 0000000..1c6239f
--- /dev/null
+++ b/pixelevents/SingleFrameEvent.py
@@ -0,0 +1,8 @@
+from operationscore.PixelEvent import *
+class SingleFrameEvent(PixelEvent):
+ def initEvent(self):
+ self.rendered = False
+ def state(self):
+ if !self.rendered:
+ return self['Color']
+ return None
diff --git a/pixelmappers/SimpleMapper.py b/pixelmappers/SimpleMapper.py
index 4d12fe4..2df24e0 100644
--- a/pixelmappers/SimpleMapper.py
+++ b/pixelmappers/SimpleMapper.py
@@ -14,17 +14,21 @@ class SimpleMapper(PixelMapper):
bestPixel = pixel
bestDist = pixelDist
return [(bestPixel,1)]
- elif type(type(str)):
- #[{x}>5,{y}<k]
+ else:
+ #{x}>5,{y}<k
#TODO: we should probably encapsulate this somewhere
ret = []
eventLocation = eventLocation.replace('{x}', 'pixel.location[0]')
eventLocation = eventLocation.replace('{y}', 'pixel.location[1]')
+ conditions = eventLocation.split(',')
+ conditionLambdas = [eval('lambda pixel:'+condition) for condition in conditions]
for pixel in screen:
try:
- preValid = eval(eventLocation)
- pixelValid = sum(preValid) == len(preValid) #TODO: some
- #optimizations possible. This might be slow in the long run
+ pixelValid = True
+ for p in conditionLambdas:
+ if p(pixel) == False:
+ pixelValid = False
+ continue
if pixelValid:
ret.append((pixel, 1))
except Exception as exp:
diff --git a/tests/TestComponentRegistry.py b/tests/TestComponentRegistry.py
new file mode 100644
index 0000000..1acd0c8
--- /dev/null
+++ b/tests/TestComponentRegistry.py
@@ -0,0 +1,11 @@
+import unittest
+import util.ComponentRegistry as compReg
+class TestComponentRegistry(unittest.TestCase):
+ def setUp(self):
+ compReg.initRegistry()
+ def tearDown(self):
+ compReg.clearRegistry()
+ def test_register_component(self):
+ comp = SmootCoreObject({'Id': obj1})
+ compReg.registerComponent(comp)
+
diff --git a/util/ComponentRegistry.py b/util/ComponentRegistry.py
index 119ce18..0518f56 100644
--- a/util/ComponentRegistry.py
+++ b/util/ComponentRegistry.py
@@ -1,43 +1,40 @@
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(
+import hashlib
+from logger import main_log
+#TODO: make component registry a singleton
+def initRegistry():
+ #TODO: don't overwrite existing registry
+ 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 initRegistry():
- globals()['Registry'] = {}
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')
+ except KeyError:
+ cid = getNewId()
+ component['Id'] = cid
+ main_log.debug(cid + 'automatically assigned')
+ globals()['Registry'][cid] = component
+ return cid
#def registerDefault(
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()
+ while trialId in globals()['Registry']:
+ trialKey += 1
+ trialId = hashlib.md5(str(trialKey)).hexdigest()
+ return trialId
diff --git a/util/Geo.py b/util/Geo.py
index a9243de..be3e93e 100644
--- a/util/Geo.py
+++ b/util/Geo.py
@@ -4,7 +4,6 @@ from bisect import *
import random
def pointWithinBoundingBox(point, bb): #this could be in 4 lines, but I'm lazy.
return sum([(point[i % 2] <= bb[i]) == (i>1) for i in range(4)]) == 4
-print pointWithinBoundingBox((118,21), (10,8,298,42))
def addLocations(l1,l2):
return tuple([l1[i]+l2[i] for i in range(len(l1))])
def gaussian(x,height,center,width):
@@ -13,9 +12,12 @@ def gaussian(x,height,center,width):
c=width
return a*math.exp(-((x-b)**2)/(2*c**2))
def dist(l1, l2):
- return math.sqrt(sum([(l1[i]-l2[i])**2 for i in range(len(l1))]))
+ return math.sqrt((l1[0]-l2[0])**2+(l1[1]-l2[1])**2)
+ #return math.sqrt(sum([(l1[i]-l2[i])**2 for i in range(len(l1))]))
def randomLoc(boundingBox): #TODO: make less shitty
loc = []
loc.append(random.randint(0, boundingBox[0]))
loc.append(random.randint(0, boundingBox[1]))
return tuple(loc)
+def approxexp(x):
+ return 1+x+x**2/2+x**3/6
diff --git a/util/PacketComposition.py b/util/PacketComposition.py
index b323d54..3574170 100644
--- a/util/PacketComposition.py
+++ b/util/PacketComposition.py
@@ -22,14 +22,25 @@ def composePixelStripData(pixelStrip,currentTime=timeops.time()):
#color = pixelStrip.pixels[i].state()
#packet[i:i+2] = color
# return bytearray(packet)
-def composePixelStripPacket(pixelStrip,port, currentTime):
+cache = {}
+def memoize(f):
+ def helper(x):
+ if x not in cache:
+ cache[x] = f(x)
+ return cache[x]
+ return helper
+@memoize
+def cachePacketHeader(port):
packet = bytearray()
- data = composePixelStripData(pixelStrip, currentTime)
subDict = dict(kinetDict)
subDict['len'] = 38000 #I have no idea why this works.
subDict['port'] = port
packet.extend(kinetPortOutPacket(subDict))
packet.append(0x0)
+ return packet
+def composePixelStripPacket(pixelStrip,port, currentTime):
+ packet = bytearray(cachePacketHeader(port))
+ data = composePixelStripData(pixelStrip, currentTime)
packet.extend(data)
return packet
def kinetHeader():