From f45b5e262c394cf00ef88f7fca1eab1b4de0fec9 Mon Sep 17 00:00:00 2001 From: Russell Cohen Date: Thu, 20 Jan 2011 14:57:43 -0500 Subject: Rewrite of Behavior parent class to suck less. Lots of bug fixes. Added 'RestrictLocation' which allows events to fire based on their location. --- behaviors/BehaviorChain.py | 4 ++-- behaviors/ColorChangerBehavior.py | 2 +- behaviors/DebugBehavior.py | 2 +- behaviors/EchoBehavior.py | 2 +- behaviors/ModifyParam.py | 8 +++----- behaviors/RandomWalk.py | 1 + behaviors/RecursiveDecay.py | 3 ++- behaviors/RedShift.xml | 9 +++++++++ behaviors/RestrictLocation.py | 28 ++++++++++++++++++++++++++-- config/Outdoor.xml | 20 +++++++++++++++++--- operationscore/Behavior.py | 29 ++++++++--------------------- operationscore/PixelEvent.py | 1 + pixelcore/PixelEventManager.py | 2 ++ pixelcore/Screen.py | 3 --- pixelmappers/SimpleMapper.py | 1 - setup.sh | 0 16 files changed, 74 insertions(+), 41 deletions(-) create mode 100644 behaviors/RedShift.xml create mode 100644 pixelcore/PixelEventManager.py mode change 100755 => 100644 setup.sh diff --git a/behaviors/BehaviorChain.py b/behaviors/BehaviorChain.py index e15bd23..39f4402 100644 --- a/behaviors/BehaviorChain.py +++ b/behaviors/BehaviorChain.py @@ -29,8 +29,8 @@ 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 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/RandomWalk.py b/behaviors/RandomWalk.py index dfe6716..fd6c2c8 100644 --- a/behaviors/RandomWalk.py +++ b/behaviors/RandomWalk.py @@ -3,6 +3,7 @@ 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 = [] 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 @@ + + behaviors.RestrictLocation + + (255,0,255) + Color + {x}>100 + + + diff --git a/behaviors/RestrictLocation.py b/behaviors/RestrictLocation.py index 649500f..febc9ed 100644 --- a/behaviors/RestrictLocation.py +++ b/behaviors/RestrictLocation.py @@ -1,12 +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']} - - def processInput( + 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/config/Outdoor.xml b/config/Outdoor.xml index e3a74f4..e137ec4 100644 --- a/config/Outdoor.xml +++ b/config/Outdoor.xml @@ -70,6 +70,9 @@ False + + behaviors/RedShift.xml + behaviors/RandomColor.xml @@ -114,7 +117,7 @@ behaviors/LoopAndDie.xml - 300 + 30 @@ -123,7 +126,7 @@ runcolordecay pygame - randomLoc + colorchange @@ -147,7 +150,7 @@ mover decay - {'mover':'randmovement'} + {'mover':'redwalk'} True gaussmap @@ -158,6 +161,16 @@ mover + + behaviors.BehaviorChain + + redwalk + + randmovement + redshift + + + behaviors.RandomWalk @@ -188,6 +201,7 @@ echo + redshift square slowdecay 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/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 77bebb6..6666235 100644 --- a/pixelcore/Screen.py +++ b/pixelcore/Screen.py @@ -92,7 +92,4 @@ class Screen: PixelEvent.addPixelEventIfMissing(responseInfo) currentTime = timeops.time() for (pixel, weight) in pixelWeightList: - if pixel == None: - pdb.set_trace() pixel.processInput(responseInfo['PixelEvent'].scale(weight), 0, currentTime) #TODO: z-index - diff --git a/pixelmappers/SimpleMapper.py b/pixelmappers/SimpleMapper.py index 396eca3..19d44c4 100644 --- a/pixelmappers/SimpleMapper.py +++ b/pixelmappers/SimpleMapper.py @@ -35,7 +35,6 @@ class SimpleMapper(PixelMapper): if pixelValid: ret.append((pixel, 1)) except Exception as exp: - pdb.set_trace() raise Exception('Bad event condition') return ret diff --git a/setup.sh b/setup.sh old mode 100755 new mode 100644 -- cgit v1.2.3