aboutsummaryrefslogtreecommitdiff
path: root/behaviors
diff options
context:
space:
mode:
Diffstat (limited to 'behaviors')
-rw-r--r--behaviors/Accelerate.xml2
-rw-r--r--behaviors/AddPixelEvent.py3
-rw-r--r--behaviors/AllPixels.py11
-rw-r--r--behaviors/AllPixelsLeft.py1
-rw-r--r--behaviors/BehaviorChain.py23
-rw-r--r--behaviors/ColorChangerBehavior.py18
-rw-r--r--behaviors/ControllerOSC.py62
-rw-r--r--behaviors/DebugBehavior.py3
-rw-r--r--behaviors/DecayBehavior.py1
-rw-r--r--behaviors/Deccelerate.xml9
-rw-r--r--behaviors/DimColor.xml8
-rw-r--r--behaviors/EchoBehavior.py7
-rw-r--r--behaviors/Expand.py22
-rw-r--r--behaviors/ExpandingColorZones.py21
-rw-r--r--behaviors/Flasher.py41
-rw-r--r--behaviors/MITDoors.py28
-rw-r--r--behaviors/MobileShakeBehavior.py26
-rw-r--r--behaviors/ModifyParam.py14
-rw-r--r--behaviors/MoveBehavior.py35
-rw-r--r--behaviors/RandomSetBrightColorBehavior.py14
-rw-r--r--behaviors/RandomWalk.py3
-rw-r--r--behaviors/RecursiveDecay.py5
-rw-r--r--behaviors/ResponseMover.py14
-rw-r--r--behaviors/RestrictLocation.py10
-rw-r--r--behaviors/RiseFall.py46
-rw-r--r--behaviors/RiseFall.xml7
-rw-r--r--behaviors/RunningBehavior.py5
-rw-r--r--behaviors/Sink.py42
-rwxr-xr-xbehaviors/SmootWind.py43
-rw-r--r--behaviors/Square.py26
-rw-r--r--behaviors/SynchTest.py12
-rw-r--r--behaviors/TimedDie.py15
-rw-r--r--behaviors/Timeout.py16
-rw-r--r--behaviors/TouchOSC.py5
-rw-r--r--behaviors/XYMove.py7
35 files changed, 572 insertions, 33 deletions
diff --git a/behaviors/Accelerate.xml b/behaviors/Accelerate.xml
index f9de077..c78195b 100644
--- a/behaviors/Accelerate.xml
+++ b/behaviors/Accelerate.xml
@@ -3,6 +3,6 @@
<Args>
<ParamType>Sensor</ParamType>
<ParamName>StepSize</ParamName>
- <ParamOp>{val}*1.1</ParamOp>
+ <ParamOp>{val}*1.01</ParamOp>
</Args>
</Behavior>
diff --git a/behaviors/AddPixelEvent.py b/behaviors/AddPixelEvent.py
index 7f134e1..da3f7c2 100644
--- a/behaviors/AddPixelEvent.py
+++ b/behaviors/AddPixelEvent.py
@@ -2,6 +2,9 @@ from operationscore.Behavior import *
import util.Strings as Strings
from logger import main_log
class AddPixelEvent(Behavior):
+ """AddPixelEvent is a behavior to append an arbitrary PixelEvent to a behavior response. The
+ classname of the PixelEvent should be specified in the Class field of Args. All arguments normally
+ passed to the PixelEvent should also be specified in Args."""
def behaviorInit(self):
[module, className] = self['Class'].split('.')
try:
diff --git a/behaviors/AllPixels.py b/behaviors/AllPixels.py
index e155e55..7f66ad6 100644
--- a/behaviors/AllPixels.py
+++ b/behaviors/AllPixels.py
@@ -1,6 +1,9 @@
from operationscore.Behavior import *
class AllPixels(Behavior):
- def processResponse(self, sensorInputs, recursiveInputs):
- for sensory in sensorInputs:#TODO: consider replicating the dict
- sensory['Location'] = 'True'
- return (sensorInputs, recursiveInputs)
+ """Turns on all Pixels in the installation. Must use SimpleMapper, or other Mapper supporting
+ conditional pixel locations."""
+
+ def processResponse(self, sensorInputs, recursiveInputs):
+ for sensory in sensorInputs:#TODO: consider replicating the dict
+ sensory['Location'] = 'True'
+ return (sensorInputs, recursiveInputs)
diff --git a/behaviors/AllPixelsLeft.py b/behaviors/AllPixelsLeft.py
index b48bfc1..b223156 100644
--- a/behaviors/AllPixelsLeft.py
+++ b/behaviors/AllPixelsLeft.py
@@ -2,6 +2,7 @@ from operationscore.Behavior import *
import util.ComponentRegistry as compReg
import pdb
class AllPixelsLeft(Behavior):
+ """Behavior which returns all points left of its input. No Args."""
def processResponse(self, sensorInputs, recursiveInputs):
for sensory in sensorInputs:
xLoc = sensory['Location'][0]
diff --git a/behaviors/BehaviorChain.py b/behaviors/BehaviorChain.py
index 39f4402..631ad98 100644
--- a/behaviors/BehaviorChain.py
+++ b/behaviors/BehaviorChain.py
@@ -3,6 +3,24 @@ import util.ComponentRegistry as compReg
from logger import main_log
import pdb
class BehaviorChain(Behavior):
+ """BehaviorChain is a class which chains together multiple behavior. BehaviorChain is in itself a
+ behavior, and behaves and can be used accordingly. BehaviorChain also supports recursive hooks to
+ be set on its constituent behaviors. ChainedBehaviors should be specified in <Args> as follows:
+
+ <ChainedBehaviors>
+ <Id>behavior1Id</Id>
+ <Id>behavior2Id</Id>
+ </ChainedBehaviors>
+
+ Behaviors may also be appended programmatically via the appendBehavior method.
+
+ Recursive hooks should be specified with Python dict syntax as follows:
+
+ <RecursiveHooks>{'behavior1Id':'hookid'}</RecursiveHooks>
+
+ Behavior Chain manages all recurrences that its constituents propogate. At this point, it does not
+ support recurrences in its hooks."""
+
def behaviorInit(self):
self.feedback = {} #dictionary to allow feedback of recursives
self.hooks = self['RecursiveHooks']
@@ -27,11 +45,10 @@ class BehaviorChain(Behavior):
hookBehavior.immediateProcessInput(recurrence, \
[])
if hookRecurrence != []:
- main_log.warn('Hook recurrences are not currently supported. Implement it\
-yourself or bug russell')
+ main_log.warn('Hook recurrences are not currently supported.')
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)
diff --git a/behaviors/ColorChangerBehavior.py b/behaviors/ColorChangerBehavior.py
index 2a8d974..e2f8bd3 100644
--- a/behaviors/ColorChangerBehavior.py
+++ b/behaviors/ColorChangerBehavior.py
@@ -2,12 +2,26 @@ from operationscore.Behavior import *
import util.ColorOps as color
import pdb
class ColorChangerBehavior(Behavior):
+ """ColorChangerBehavior is a behavior for adding colors to responses. If given no arguments, it
+ will generate a random color. If it is given a list of colors [as below] it will pick randomly
+ from them.
+
+ <ColorList>
+ <Color>(255,0,0)</Color>
+ <Color>(30,79,200)</Color>
+ </ColorList>
+
+ ColorList also supports specification of a single color."""
+
def processResponse(self, sensorInputs, recursiveInputs):
ret = []
for sensory in sensorInputs:
- newDict = dict(sensory) #don't run into shallow copy issues
+ newDict = dict(sensory)
if self['ColorList'] != None:
- newDict['Color'] = color.chooseRandomColor(self['ColorList']) #TODO: this doesn't work.
+ if isinstance(self['ColorList'], list):
+ newDict['Color'] = color.chooseRandomColor(self['ColorList']) #Pick randomly
+ else:
+ newDict['Color'] = self['ColorList'] #Unless there is only one
else:
newDict['Color'] = color.randomColor()
ret.append(newDict)
diff --git a/behaviors/ControllerOSC.py b/behaviors/ControllerOSC.py
new file mode 100644
index 0000000..05d2e7d
--- /dev/null
+++ b/behaviors/ControllerOSC.py
@@ -0,0 +1,62 @@
+from operationscore.Behavior import *
+from logger import main_log
+#import util.ColorOps as color
+import colorsys
+from numpy import array
+import pdb
+import util.ComponentRegistry as compReg
+
+speedfactor = 15
+vel_decay = .9
+
+def constrainLocation(v,c):
+ if v[0] > c[0]:
+ v[0] = c[0]
+ elif v[0]<0:
+ v[0] = 0
+
+ if v[1] > c[1]:
+ v[1] = c[1]
+ elif v[1]<0:
+ v[1] = 0
+
+ return v
+
+class ControllerOSC(Behavior):
+ def behaviorInit(self):
+ self.xy = array((0,0))
+ self.v_xy = array((0,0))
+ self.v_decay = vel_decay
+
+ self.start_hsv = [0,1,1]
+ self.dest_hsv = [0,1,1]
+ self.ssize = compReg.getComponent('Screen').getSize()[-2:] #896 x 310
+
+ def processResponse(self, sensorInputs, recursiveInputs):
+ ret = []
+ if sensorInputs:
+ data = sensorInputs[-1]#for data in sensorInputs:
+ if data['Path'] == '/sixaxis/xy':
+ #try:
+ x = data['Value'][0]
+ y = data['Value'][1]
+ if y < 0:
+ self.start_hsv[1] = 1.0+y #s
+ else:
+ self.start_hsv[2] = 1.0-y
+ self.start_hsv[0] = (x+1)/2.
+ elif data['Path'] == '/sixaxis/lrud':
+ val=data['Value']
+ vy = val[3]-val[2]
+ vx = val[1]-val[0]
+ #pdb.set_trace()
+ #self.v_xy = (val[1]*ssize[0], (1.0-val[0])*ssize[1])
+ self.v_xy = array((vx, vy)) * speedfactor
+ else:
+ main_log.error('Sensor Inputs: ' + str(sensorInputs))
+ self.xy = self.xy + self.v_xy
+ constrainLocation(self.xy,self.ssize)
+ self.v_xy *= self.v_decay
+ ret.append({'Color':[i*255. for i in colorsys.hsv_to_rgb(*self.start_hsv)],'Location':(int(self.xy[0]), int(self.xy[1]))})
+
+ return (ret, [])
diff --git a/behaviors/DebugBehavior.py b/behaviors/DebugBehavior.py
index 17383db..8f81954 100644
--- a/behaviors/DebugBehavior.py
+++ b/behaviors/DebugBehavior.py
@@ -2,6 +2,9 @@ from operationscore.Behavior import *
from logger import main_log
import pdb
class DebugBehavior(Behavior):
+ """DebugBehavior simply writes all of its inputs to the logs, currently at the ERROR level for
+ easy visibility. Will be changed to DEBUG or INFO in the future"""
+
def processResponse(self, sensorInputs, recursiveInputs):
if sensorInputs != []:
main_log.error('Sensor Inputs: ' + str(sensorInputs))
diff --git a/behaviors/DecayBehavior.py b/behaviors/DecayBehavior.py
index c1f6f92..f19ffc8 100644
--- a/behaviors/DecayBehavior.py
+++ b/behaviors/DecayBehavior.py
@@ -3,6 +3,7 @@ from pixelevents.DecayEvent import *
import util.Strings as Strings
import pdb
class DecayBehavior(Behavior):
+ """DecayBehavior is obsolete. Use AddPixelEvent instead"""
def processResponse(self, sensorInputs, recursiveInputs):
ret = []
for sensory in sensorInputs:
diff --git a/behaviors/Deccelerate.xml b/behaviors/Deccelerate.xml
new file mode 100644
index 0000000..e64e61d
--- /dev/null
+++ b/behaviors/Deccelerate.xml
@@ -0,0 +1,9 @@
+
+<Behavior>
+ <Class>behaviors.ModifyParam</Class>
+ <Args>
+ <ParamType>Sensor</ParamType>
+ <ParamName>StepSize</ParamName>
+ <ParamOp>{val}*.98</ParamOp>
+ </Args>
+</Behavior>
diff --git a/behaviors/DimColor.xml b/behaviors/DimColor.xml
new file mode 100644
index 0000000..ef98fee
--- /dev/null
+++ b/behaviors/DimColor.xml
@@ -0,0 +1,8 @@
+<Behavior>
+ <Class>behaviors.ModifyParam</Class>
+ <Args>
+ <ParamType>Sensor</ParamType>
+ <ParamName>Color</ParamName>
+ <ParamOp>[chan*.98 for chan in {val}]</ParamOp>
+ </Args>
+</Behavior>
diff --git a/behaviors/EchoBehavior.py b/behaviors/EchoBehavior.py
index 589c42b..c4af7c0 100644
--- a/behaviors/EchoBehavior.py
+++ b/behaviors/EchoBehavior.py
@@ -2,11 +2,16 @@ from operationscore.Behavior import *
import util.Strings as Strings
import pdb
class EchoBehavior(Behavior):
+ """EchoBehavior generates a RED response at all locations specified in sensorInputs. Useful for
+ debugging"""
def processResponse(self, sensorInputs, recursiveInputs):
ret = []
for sensory in sensorInputs:
outDict = {}
outDict[Strings.LOCATION] = sensory[Strings.LOCATION]
- outDict['Color'] = (255,0,0)
+ if self['Color'] != None:
+ outDict['Color'] = self['Color']
+ else:
+ outDict['Color'] = (255,0,0)
ret.append(outDict)
return (ret, [])
diff --git a/behaviors/Expand.py b/behaviors/Expand.py
new file mode 100644
index 0000000..f017c16
--- /dev/null
+++ b/behaviors/Expand.py
@@ -0,0 +1,22 @@
+from operationscore.Behavior import *
+class Expand(Behavior):
+ """Expand is a behavior that generates a response that grows horizontally starting a location
+ specifed in input. Required Args:
+ <ExpandRate>123</ExpandRate> which is the expandrate in units/response"""
+
+ def processResponse(self, sensorInputs, recurs):
+ ret = []
+ for data in sensorInputs:
+ if not 'Left' in data: #If this is the first time we have seen this input
+ data['Left'] = data['Location'][0]
+ data['Right'] = data['Location'][0]
+ data['ExpandRate'] = self['ExpandRate']
+
+ data = dict(data)
+ data['Left'] -= data['ExpandRate']
+ data['Right'] += data['ExpandRate']
+ data['Location'] = "{x}>" + str(data['Left']) + ", {x}<" +\
+ str(data['Right'])+", {y}<50"
+ ret.append(data)
+ return (ret, [])
+
diff --git a/behaviors/ExpandingColorZones.py b/behaviors/ExpandingColorZones.py
new file mode 100644
index 0000000..75be761
--- /dev/null
+++ b/behaviors/ExpandingColorZones.py
@@ -0,0 +1,21 @@
+from operationscore.Behavior import *
+from logger import main_log
+class ExpandingColorZones(Behavior):
+ def behaviorInit(self):
+ self.mapping = {'s001':[(132,0),(255,0,0)], 's002':[(400,0), (0,255,0)],
+ 's003':[(668,0),
+ (0,0,255)]}
+ self.mappingkey = 'data'
+ def processResponse(self, sensorInputs, recursiveInputs):
+ ret = []
+ for data in sensorInputs:
+ print data
+ data = dict(data)
+ if self.mappingkey in data:
+ try:
+ data['Location'], data['Color'] =\
+ self.mapping[data[self.mappingkey]]
+ ret.append(data)
+ except:
+ main_log.warn('Bad mapping key. Expanding Color Zones.')
+ return (ret,[])
diff --git a/behaviors/Flasher.py b/behaviors/Flasher.py
new file mode 100644
index 0000000..1d79d41
--- /dev/null
+++ b/behaviors/Flasher.py
@@ -0,0 +1,41 @@
+
+from operationscore.Behavior import *
+import util.ColorOps as colorops
+import pdb
+class Flasher(Behavior):
+ """Implements a pulsing/flashing behavior.
+ Jim Salem: jsalem@gmail.com
+
+ Args:
+ Factor - The speed of flashing. Must be b/w 0 and 1. Default is .95
+ """
+ def processResponse(self, sensorInputs, recursiveInputs):
+ ret = []
+ for response in sensorInputs:
+ # Get the multiplier
+ if self['Factor'] != None:
+ factor = self['Factor']
+ else:
+ factor = 0.95
+ # Initialize the first time
+ if not 'FireflyStartColor' in response:
+ response['FireflyValue'] = 1.0
+ response['FireflyDir'] = 1
+ response['FireflyStartColor'] = response['Color'];
+ else:
+ # Update the current value
+ if response['FireflyDir'] == 1:
+ response['FireflyValue'] = response['FireflyValue'] * factor
+ if response['FireflyValue'] <= 0.01:
+ response['FireflyValue'] = 0.01
+ response['FireflyDir'] = 0
+ else:
+ response['FireflyValue'] = response['FireflyValue'] / factor
+ if response['FireflyValue'] >= 1.0:
+ response['FireflyValue'] = 1.0
+ response['FireflyDir'] = 1
+
+ # Compute the color
+ response['Color'] = colorops.multiplyColor(response['FireflyStartColor'], response['FireflyValue'])
+ ret.append(response)
+ return (ret, []) #no direct ouput
diff --git a/behaviors/MITDoors.py b/behaviors/MITDoors.py
new file mode 100644
index 0000000..cee47f0
--- /dev/null
+++ b/behaviors/MITDoors.py
@@ -0,0 +1,28 @@
+from operationscore.Behavior import *
+import math
+import util.ComponentRegistry as compReg
+class MITDoors(Behavior):
+ """MITDoors is a case-specific behavior to map keypresses to specific locations. Written for
+ Kuan 1/26/11 by RCOH"""
+
+ def behaviorInit(self):
+ self.keymapping = {'q':[2,19], 'w':[22,36], 'e':[37,49], 'r':[52,69], 't':[76,91], 'y':[94,105],
+ 'u':[106,117], 'i':[123,154], 'o':[158,161], 'p':[164,167], '[':[172,184]}
+ screenWidth = compReg.getComponent('Screen').getSize()[2] #(minx, miny,maxx, maxy)
+ maxKey = max([max(self.keymapping[v]) for v in self.keymapping])
+ mult = screenWidth / float(maxKey)
+ for k in self.keymapping:
+ self.keymapping[k] = [int(val*mult) for val in self.keymapping[k]]
+ def processResponse(self, sensorInputs, recursiveInputs):
+ ret = []
+ for data in sensorInputs:
+ key = chr(data['Key'])
+ if key in self.keymapping:
+ bounds = self.keymapping[key]
+ data = dict(data)
+ data['Left'], data['Right'] = bounds
+ data['Bottom'] = self['Bottom']
+ data['Location'] = (sum(bounds) / 2., self['Bottom'])
+ data['Oscillate'] = False
+ ret.append(data)
+ return (ret, [])
diff --git a/behaviors/MobileShakeBehavior.py b/behaviors/MobileShakeBehavior.py
new file mode 100644
index 0000000..b05cb5f
--- /dev/null
+++ b/behaviors/MobileShakeBehavior.py
@@ -0,0 +1,26 @@
+from operationscore.Behavior import *
+import util.ComponentRegistry as compReg
+import util.Strings as Strings
+
+class MobileShakeBehavior(Behavior):
+ def behaviorInit(self):
+ self.mapper = None
+
+ def processResponse(self, sensorInputs, recursiveInputs):
+ if self.mapper == None:
+ try:
+ self.mapper = compReg.getComponent('mobilegaussmap')
+ except KeyError:
+ pass
+
+ #print sensorInputs
+ for sInput in sensorInputs:
+ if 'Shake' in sInput and sInput['Shake'] == 1:
+ #print 'increase!'
+ self.mapper.argDict['Width'] += 30
+ #self.mapper.argDict['CutoffDist'] += 20
+ sInput['Shake'] = 0
+ print 'Width:' + str(compReg.getComponent('mobilegaussmap').argDict['Width'])
+ #print 'CutoffDist: '+ str(compReg.getComponent('mobilegaussmap').argDict['CutoffDist'])
+
+ return (sensorInputs, recursiveInputs)
diff --git a/behaviors/ModifyParam.py b/behaviors/ModifyParam.py
index f589e05..0ef3a60 100644
--- a/behaviors/ModifyParam.py
+++ b/behaviors/ModifyParam.py
@@ -1,9 +1,20 @@
from operationscore.Behavior import *
+import math
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):
+ """ModifyParam is a powerful class to perform an action on a specified key in the Argument
+ Dictionary of a response. Specify:
+ <ParamType> -- Sensor or Recurse
+ <ParamName> -- The name of the parameter you wish to modify
+ <ParamOp> -- The modification you wish to do. Use {val} to specify the current value of the
+ parameter in question. Special hooks for {x} and {y} also exist to access the x and y
+ locations."""
+
def processResponse(self, sensorInputs, recursiveInputs):
paramType = self['ParamType']
+ if paramType == None:
+ paramType = 'Sensor'
paramName = self['ParamName']
paramOp = str(self['ParamOp'])
if paramType == 'Sensor':
@@ -16,6 +27,9 @@ class ModifyParam(Behavior):
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
+ #TODO: move elsewhere
+ paramOp = paramOp.replace('{y}', "behaviorInput['Location'][1]")
+ paramOp = paramOp.replace('{x}', "behaviorInput['Location'][0]")
behaviorInput[paramName] = eval(paramOp)
if paramType == 'Sensor': #return accordingly
return (searchSet, recursiveInputs)
diff --git a/behaviors/MoveBehavior.py b/behaviors/MoveBehavior.py
new file mode 100644
index 0000000..6e7fc6a
--- /dev/null
+++ b/behaviors/MoveBehavior.py
@@ -0,0 +1,35 @@
+from operationscore.Behavior import *
+#import util.ComponentRegistry as compReg
+#import util.Geo as Geo
+#import util.Strings as Strings
+
+class MoveBehavior(Behavior):
+ """Moves current location by the x and y components of sensorInput. Uses recurrences to track
+ current input. @Author: Euguene"""
+
+ def processResponse(self, sensorInputs, recursiveInputs):
+ 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:
+ if 'type' in sensorInput and sensorInput['type'] == 1:
+ currDict['Shake'] = 0
+ currDict['Location'] = (currDict['Location'][0] - sensorInput['x'] * self['XStep'], \
+ currDict['Location'][1] + sensorInput['y'] * self['YStep'])
+ currDict['Color'] = [sensorInput['r'], sensorInput['g'], sensorInput['b']]
+ elif sensorInput['type'] == 2:
+ currDict['Shake'] = 1
+ #currDict['Force'] = sensorInput['force']
+ ret.append(currDict)
+ #print ret
+ return (ret, ret)
+
+ else: # if not, return current recursive location.
+ #print currRecLocs
+ return (currRecLocs, currRecLocs)
diff --git a/behaviors/RandomSetBrightColorBehavior.py b/behaviors/RandomSetBrightColorBehavior.py
new file mode 100644
index 0000000..f278858
--- /dev/null
+++ b/behaviors/RandomSetBrightColorBehavior.py
@@ -0,0 +1,14 @@
+from operationscore.Behavior import *
+import util.ColorOps as color
+import pdb
+import colorsys
+import random
+class RandomSetBrightColorBehavior(Behavior):
+ """Sets a random color that is bright."""
+ def processResponse(self, sensorInputs, recursiveInputs):
+ ret = []
+ for sensory in sensorInputs:
+ newDict = dict(sensory)
+ newDict['Color'] = color.randomBrightColor()
+ ret.append(newDict)
+ return (ret, [])
diff --git a/behaviors/RandomWalk.py b/behaviors/RandomWalk.py
index fd6c2c8..c9049af 100644
--- a/behaviors/RandomWalk.py
+++ b/behaviors/RandomWalk.py
@@ -5,6 +5,9 @@ import util.Strings as Strings
import random
import pdb
class RandomWalk(Behavior):
+ """Behavior to move the curent location by a random distance specified by
+ <StepSize> -- StepSize in units/response"""
+
def processResponse(self, sensors, recursives):
ret = []
s = self['StepSize']
diff --git a/behaviors/RecursiveDecay.py b/behaviors/RecursiveDecay.py
index 218813d..0ae21ea 100644
--- a/behaviors/RecursiveDecay.py
+++ b/behaviors/RecursiveDecay.py
@@ -1,6 +1,11 @@
from operationscore.Behavior import *
import pdb
class RecursiveDecay(Behavior):
+ """RecursiveDecay is an event to allow recursive hooks to stop recursing after a certain number
+ of iterations specified in
+ <InitialResponseCount> -- Int, number of total responses.
+ Designed to be used as part of a recursive hook.
+ """
def processResponse(self, sensorInputs, recursiveInputs):
ret = []
for response in sensorInputs:
diff --git a/behaviors/ResponseMover.py b/behaviors/ResponseMover.py
index e1faccb..3d559df 100644
--- a/behaviors/ResponseMover.py
+++ b/behaviors/ResponseMover.py
@@ -1,15 +1,11 @@
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.
-#Add a recursive hook to control the movement.
class ResponseMover(Behavior):
+ """ResponseMover is a scaffold for behaviors that spawn 'walkers' which act autonomously on input.
+ To control the movment, use the behavior as part of a BehaviorChain and add a recursive hook which
+ modulates the location."""
+
def processResponse(self, sensorInputs, recursiveInputs):
- newResponses = sensorInputs
- ret = []
- for recurInput in recursiveInputs:
- outDict = dict(recurInput)
- ret.append(outDict)
- ret += newResponses
- return (ret, ret)
+ return (recursiveInputs, recursiveInputs+sensorInputs)
diff --git a/behaviors/RestrictLocation.py b/behaviors/RestrictLocation.py
index f6c26ff..5e12440 100644
--- a/behaviors/RestrictLocation.py
+++ b/behaviors/RestrictLocation.py
@@ -6,6 +6,16 @@ import util.Strings as Strings
import random
import pdb
class RestrictLocation(Behavior):
+ """RestrictLocation is a Behavior which does an action -- A ModifyParam, actually, when a certain
+ location based condition is met. It takes arguments as follows:
+
+ <Action> -- Operation to perform, using ModifyParam syntax. Use {val} to reference the variable
+ specified by ParamName.
+ <ParamName> -- the name of the parameter to modify.
+ <LocationRestriction> -- either a tuple of (xmin,ymin,xmax,ymax) or a python-correct conditional. Use {x} and
+ {y} to reference x and y. Use &lt; and &gt; to get < and > in XML. EG:
+ <LocationRestriction>{x}&lt;0 or {x}&gt;800</LocationRestriction>"""
+
def behaviorInit(self):
action = self['Action']
modifyParamArgs = {'ParamType': 'Sensor',
diff --git a/behaviors/RiseFall.py b/behaviors/RiseFall.py
new file mode 100644
index 0000000..eea2283
--- /dev/null
+++ b/behaviors/RiseFall.py
@@ -0,0 +1,46 @@
+from operationscore.Behavior import *
+import math
+import util.TimeOps as timeOps
+#Required Args:
+#Period (ms), MaxHeight, Width
+class RiseFall(Behavior):
+ """RiseFall is a behavior that creates a rising and falling column of light. Specify:
+ <MaxHeight> -- the maximum height that it rises to.
+ <Width> -- the width of the column OR <Left> and <Right>
+ <Period> -- the period of oscillation in ms
+
+ Designed to be used as part of a recursive hook.
+ """
+
+ def processResponse(self, sensorInputs, recurInputs):
+ ret = []
+ for data in sensorInputs:
+ #first time with behavior:
+ data = dict(data)
+ if not 'StartTime' in data:
+ data['StartTime'] = timeOps.time()
+ data['Period'] = self['Period']
+ data['MaxHeight'] = self['MaxHeight'] #Consider just using +=
+ if not 'Bottom' in data:
+ data['Bottom'] = data['Location'][1]
+ if 'Width' in self: #TODO: improve
+ data['Width'] = self['Width']
+ data['Left'] = data['Location'][0]-data['Width']/2.
+ data['Right'] = data['Location'][0]+data['Width']/2.
+ currentTime = timeOps.time()
+ deltaTime = currentTime-data['StartTime']
+ #if data['Oscillate'] == True:
+ data['Height'] = data['MaxHeight']*math.sin(deltaTime/data['Period']*(math.pi*2))
+ #else:
+ # data['Height'] = data['MaxHeight']
+ #if (currentTime-data['StartTime']) > data['Period']:
+ # del data['StartTime']
+
+ data['Location'] = "{x}>"+str(data['Left']) + ", " +\
+ "{x}<"+str(data['Right'])+", {y}<" + str(data['Bottom']) + ",\
+ {y}>"+str(data['Bottom']-data['Height'])
+
+ ret.append(data)
+ return (ret, [])
+
+
diff --git a/behaviors/RiseFall.xml b/behaviors/RiseFall.xml
new file mode 100644
index 0000000..eaadd7b
--- /dev/null
+++ b/behaviors/RiseFall.xml
@@ -0,0 +1,7 @@
+<Behavior>
+ <Class>behaviors.RiseFall</Class>
+ <Args>
+ <Period>2000</Period>
+ <MaxHeight>50</MaxHeight>
+ </Args>
+</Behavior>
diff --git a/behaviors/RunningBehavior.py b/behaviors/RunningBehavior.py
index 5eb33f7..ab3dc80 100644
--- a/behaviors/RunningBehavior.py
+++ b/behaviors/RunningBehavior.py
@@ -3,6 +3,11 @@ import util.ComponentRegistry as compReg
import util.Geo as Geo
import pdb
class RunningBehavior(Behavior):
+ """RunningBehavior is a straightforward behavior that makes a Location run back and forth across
+ a screen. Specify:
+ <StepSize> -- the length of movment in units when the response moves.
+ """
+
def processResponse(self, sensorInputs, recursiveInputs):
newResponses = sensorInputs
ret = []
diff --git a/behaviors/Sink.py b/behaviors/Sink.py
new file mode 100644
index 0000000..52d0be2
--- /dev/null
+++ b/behaviors/Sink.py
@@ -0,0 +1,42 @@
+
+from operationscore.Behavior import *
+import math
+import util.TimeOps as timeOps
+#Required Args:
+#Period (ms), MaxHeight, Width
+class Sink(Behavior):
+ """RiseFall is a behavior that creates a rising and falling column of light. Specify:
+ <MaxHeight> -- the maximum height that it rises to.
+ <Width> -- the width of the column OR <Left> and <Right>
+ <Period> -- the period of oscillation in ms
+
+ Designed to be used as part of a recursive hook.
+ """
+
+ def processResponse(self, sensorInputs, recurInputs):
+ ret = []
+ for data in sensorInputs:
+ #first time with behavior:
+ data = dict(data)
+ if not 'StartTime' in data:
+ data['StartTime'] = timeOps.time()
+ data['Period'] = self['Period']
+ data['MaxHeight'] = self['MaxHeight'] #Consider just using +=
+ if not 'Bottom' in data:
+ data['Bottom'] = data['Location'][1]
+ if 'Width' in self: #TODO: improve
+ data['Width'] = self['Width']
+ data['Left'] = data['Location'][0]-data['Width']/2.
+ data['Right'] = data['Location'][0]+data['Width']/2.
+ currentTime = timeOps.time()
+ deltaTime = currentTime-data['StartTime']
+ data['Height'] = data['MaxHeight']*math.cos(deltaTime/data['Period']*(math.pi*2))
+
+ data['Location'] = "{x}>"+str(data['Left']) + ", " +\
+ "{x}<"+str(data['Right'])+", {y}<" + str(data['Bottom']) + ",\
+ {y}>"+str(data['Bottom']-data['Height'])
+
+ ret.append(data)
+ return (ret, [])
+
+
diff --git a/behaviors/SmootWind.py b/behaviors/SmootWind.py
new file mode 100755
index 0000000..804183c
--- /dev/null
+++ b/behaviors/SmootWind.py
@@ -0,0 +1,43 @@
+from operationscore.Behavior import *
+import util.ComponentRegistry as compReg
+import random
+
+class SmootWind(Behavior):
+ def behaviorInit(self):
+ self.mapper = None
+ self.xFor = None
+
+ def processResponse(self, sensorInputs, recursiveInputs):
+ if self.mapper == None:
+ try:
+ self.mapper = compReg.getComponent('windgaussmap')
+ except KeyError:
+ pass
+ if self.xFor == None:
+ try:
+ self.xFor = compReg.getComponent('xfor')
+ except KeyError:
+ pass
+
+ for sensory in sensorInputs:
+ print sensory
+ # input[0] is windspeed, [1] is dir
+ if 0 in sensory and 1 in sensory:
+ windSpeed = sensory[0]
+ windDir = sensory[1]
+ #print self.mapper.argDict
+ self.mapper.argDict['Width'] = self.mapper.argDict['Width']+float(windSpeed)*2+20
+ self.xFor.argDict['ParamOp'] = self.xFor.argDict['ParamOp']+float(windSpeed)*3+10*random.random();
+ #print 'Width: ' + str(self.mapper.argDict['Width'])
+ #print 'xFor: ' + str(self.xFor.argDict['ParamOp'])
+
+ elif 'Key' in sensory:
+ if sensory['Key'] == 273:
+ self.mapper.argDict['Width'] = self.mapper.argDict['Width']+10;
+ self.xFor.argDict['ParamOp'] = self.xFor.argDict['ParamOp']+5;
+
+ elif sensory['Key'] == 274:
+ self.mapper.argDict['Width'] = self.mapper.argDict['Width']-10;
+ self.xFor.argDict['ParamOp'] = self.xFor.argDict['ParamOp']-5;
+
+ return (sensorInputs, recursiveInputs)
diff --git a/behaviors/Square.py b/behaviors/Square.py
index ecd000c..9d3223a 100644
--- a/behaviors/Square.py
+++ b/behaviors/Square.py
@@ -1,13 +1,17 @@
from operationscore.Behavior import *
class Square(Behavior):
- def processResponse(self, sensorInputs, recursiveInputs):
- for sensory in sensorInputs:#TODO: consider replicating the dict
- if 'Location' in sensory:
- xLoc = sensory['Location'][0]
- yLoc = sensory['Location'][1]
- width = self['Width']
- #sensory['Location'] = 'True'
- sensory['Location'] =\
- '{x}<'+str(xLoc+width)+',{x}>'+str(xLoc-width)+\
- ',{y}<'+str(yLoc+width)+',{y}>'+str(yLoc-width)
- return (sensorInputs, recursiveInputs)
+ """Square is a simple behavior that makes a square with side lengths Width*2 around locations in
+ the sensor input. Specify:
+ <Width> -- the sidelength/2
+ """
+
+ 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'] = 'True'
+ sensory['Location'] =\
+ '{x}<'+str(xLoc+width)+',{x}>'+str(xLoc-width)+\
+ ',{y}<'+str(yLoc+width)+',{y}>'+str(yLoc-width)
+ return (sensorInputs, recursiveInputs)
diff --git a/behaviors/SynchTest.py b/behaviors/SynchTest.py
new file mode 100644
index 0000000..e7b8acc
--- /dev/null
+++ b/behaviors/SynchTest.py
@@ -0,0 +1,12 @@
+from operationscore.Behavior import *
+from pixelevents.SynchTestEvent import *
+import pdb
+class SynchTest(Behavior):
+ def behaviorInit(self):
+ self.rendered = False
+ def processResponse(self, sensorInputs, recurs):
+ if not self.rendered:
+ self.rendered = True
+ print 'here1'
+ return ([{'Location':'True', 'PixelEvent':SynchTestEvent({'Color':(255,0,0)})}], [])
+ return ([], [])
diff --git a/behaviors/TimedDie.py b/behaviors/TimedDie.py
new file mode 100644
index 0000000..e75e9dd
--- /dev/null
+++ b/behaviors/TimedDie.py
@@ -0,0 +1,15 @@
+from operationscore.Behavior import *
+class Timeout(Behavior):
+ """Timeout is a behavior designed to be used in recursive hooks to stop responses after a certain
+ amount of time. It is the Time-version of RecursiveDecay. Specify:
+ <TimeOut> -- the time in ms that the response will run.
+ """
+
+ def processResponse(self, sensorInputs, recur):
+ ret = []
+ for data in sensorInputs:
+ if not 'StartTime' in data:
+ data['StartTime'] = timeops.time()
+ if timeops.time()-data['StartTime'] < self['Timeout']:
+ ret.append(data)
+ return (ret, [])
diff --git a/behaviors/Timeout.py b/behaviors/Timeout.py
new file mode 100644
index 0000000..14d4873
--- /dev/null
+++ b/behaviors/Timeout.py
@@ -0,0 +1,16 @@
+from operationscore.Behavior import *
+import util.TimeOps as timeops
+class Timeout(Behavior):
+ """Timeout is a behavior designed to be used in recursive hooks to stop responses after a certain
+ amount of time. It is the Time-version of RecursiveDecay. Specify:
+ <TimeOut> -- the time in ms that the response will run.
+ """
+
+ def processResponse(self,sensorInputs, recur):
+ ret = []
+ for data in sensorInputs:
+ if not 'StartTime' in data:
+ data['StartTime'] = timeops.time()
+ if timeops.time()-data['StartTime'] < self['Timeout']:
+ ret.append(data)
+ return (ret,[])
diff --git a/behaviors/TouchOSC.py b/behaviors/TouchOSC.py
index 1c41b5e..099d5e5 100644
--- a/behaviors/TouchOSC.py
+++ b/behaviors/TouchOSC.py
@@ -12,10 +12,11 @@ class TouchOSC(Behavior):
self.xy = (-1,-1)
def processResponse(self, sensorInputs, recursiveInputs):
ret = []
- for data in sensorInputs:
+ if sensorInputs:
+ data = sensorInputs[-1]#for data in sensorInputs:
if data['Path'] == '/1/fader1':
try:
- self.h = data['Value'][0]*360.0
+ self.h = data['Value'][0]
except:
pdb.set_trace()
elif data['Path'] == '/1/fader2':
diff --git a/behaviors/XYMove.py b/behaviors/XYMove.py
index 8acbba8..11cee96 100644
--- a/behaviors/XYMove.py
+++ b/behaviors/XYMove.py
@@ -1,6 +1,13 @@
from operationscore.Behavior import *
import util.Geo as Geo
class XYMove(Behavior):
+ """XYMove is a behavior designed to be used as a recursive hook to ResponseMover to move pixels by
+ XStep and YStep. As XStep and YStep are maintained in the responses itself, they can be
+ modulated to facilitate, acceleration, modulation, bouncing, etc. Specify:
+ <XStep> -- the starting XStep
+ <YStep> -- the starting YStep
+ """
+
def processResponse(self, sensor, recurs):
ret = []
for loc in sensor: