Example #1
0
    def testParallel_AllSucceed_Failure(self):
        """Can we visit a failing parallel (all succeed)?
        """
        tree = owyl.parallel(owyl.sequence(owyl.succeed(), owyl.fail()),
                             owyl.sequence(owyl.succeed(), owyl.succeed()),
                             policy=owyl.PARALLEL_SUCCESS.REQUIRE_ALL)
        v = owyl.visit(tree)

        results = [x for x in v if x is not None]
        self.assertEqual(results, [False])
Example #2
0
    def testParallel_AllSucceed_Failure(self):
        """Can we visit a failing parallel (all succeed)?
        """
        tree = owyl.parallel(owyl.sequence(owyl.succeed(),
                                           owyl.fail()),
                             owyl.sequence(owyl.succeed(),
                                           owyl.succeed()),
                             policy=owyl.PARALLEL_SUCCESS.REQUIRE_ALL)
        v = owyl.visit(tree)

        results = [x for x in v if x is not None]
        self.assertEqual(results, [False])
Example #3
0
    def testParallel_DelayedSuccess(self):
        """Can parallel succeed if child succeeds later (one succeeds)?
        """
        # Succeed after 5 iterations.
        after = 5
        tree = owyl.parallel(owyl.fail(),
                             owyl.succeedAfter(after=after),
                             policy=owyl.PARALLEL_SUCCESS.REQUIRE_ONE)
        v = owyl.visit(tree)
        results = [x for x in v if x is not None]
        self.assertEqual(results, [True])

        v = owyl.visit(tree)
        results = [x for x in v if x is not None]
        self.assertEqual(results, [True])
Example #4
0
    def testParallel_DelayedFailure(self):
        """Can parallel fail if child fails later (all succeed)?
        """
        # Fail after 5 iterations.
        after = 5
        tree = owyl.parallel(owyl.succeed(),
                             owyl.failAfter(after=after),
                             policy=owyl.PARALLEL_SUCCESS.REQUIRE_ALL)
        v = owyl.visit(tree)
        results = [x for x in v if x is not None]
        self.assertEqual(results, [False])

        v = owyl.visit(tree)
        results = [x for x in v if x is not None]
        self.assertEqual(results, [False])
Example #5
0
    def testParallel_OneSucceeds_Success(self):
        """Can we visit a suceeding parallel (one succeeds)?
        """
        tree = owyl.parallel(owyl.sequence(owyl.succeed(), owyl.succeed()),
                             owyl.sequence(owyl.succeed(), owyl.fail()),
                             policy=owyl.PARALLEL_SUCCESS.REQUIRE_ONE)
        v = owyl.visit(tree)

        results = [x for x in v if x is not None]
        self.assertEqual(results, [True])

        v = owyl.visit(tree)

        results = [x for x in v if x is not None]
        self.assertEqual(results, [True])
Example #6
0
    def testParallel_OneSucceeds_Success(self):
        """Can we visit a suceeding parallel (one succeeds)?
        """
        tree = owyl.parallel(owyl.sequence(owyl.succeed(),
                                           owyl.succeed()),
                             owyl.sequence(owyl.succeed(),
                                           owyl.fail()),
                             policy=owyl.PARALLEL_SUCCESS.REQUIRE_ONE)
        v = owyl.visit(tree)

        results = [x for x in v if x is not None]
        self.assertEqual(results, [True])

        v = owyl.visit(tree)

        results = [x for x in v if x is not None]
        self.assertEqual(results, [True])
Example #7
0
    def buildTree(self):
        """ Build the behaviour buildTree
            Building a behaviour tree is as simple as nesting 
            behaviour constructor calls.

            Building the behaviour tree
            ============================

            We use parallel to have many behaviour tree run at the same time
            - check the internet connection
            - check new tweets and reply
            - check for new emails

            Core Behaviours
            ===============

            The core behaviour are documented below in each method's docstring. They are :
            - Brain.query : queries all modules for a response to a question
            - Brain.checkinternet : check that internet connexion is available
            - Brain.checknewtweets : check that new tweets are available.
            - Brain.checknewemails : check that there are new emails


        """

        tree = owyl.parallel(
                    ### Check that internet is available
                    ####################################
                    owyl.limit(
                            owyl.repeatAlways(self.checkinternet(), debug=True, limit_period=2.4)

                        ),

                    ### Check new tweets
                    ####################################
                    self.checknewtweets(),

                    ### Check new emails
                    ####################################
                    self.checknewemails(),

                    policy=owyl.PARALLEL_SUCCESS.REQUIRE_ALL

            )

        return owyl.visit(tree, blackboard=self.bb)
Example #8
0
 def testStructureBig(self):
     tree = owyl.parallel(owyl.sequence(owyl.repeatAlways(blackboard.setBB()), owyl.log()),
                          owyl.selector(owyl.repeatUntilSucceed(blackboard.checkBB())),
                          owyl.repeatUntilFail(owyl.fail()))
     viztree = OwylTree(tree)
     structure = truncate(viztree.get_structure(), ['name', 'children'])
     self.assertEquals(structure,
                       {'name': 'parallel',
                        'children': [{'name': 'sequence',
                                      'children': [{'name': 'repeatAlways',
                                                    'children': [{'name': 'setBB',
                                                                  'children': []}]},
                                                   {'name': 'log',
                                                    'children': []}]},
                                     {'name': 'selector',
                                      'children': [{'name': 'repeatUntilSucceed',
                                                    'children': [{'name': 'checkBB',
                                                                  'children': []}]}]},
                                     {'name': 'repeatUntilFail',
                                      'children': [{'name': 'fail',
                                                    'children': []}]}]})
Example #9
0
    def buildTree(self):
        '''as simple as nesting thr behavior constructor calls'''
        tree = parallel(
            limit(repeatAlways(self.checkMyBody(), debug=True),
                  limit_period=1),  #*children, **kwargs
            ### Look & See
            ############################
            repeatAlways(
                sequence(
                    self.seeSomethingNew(
                    ),  #*children, **kwargs. run until fails
                    self.headtrack(),
                    self.recogThat()), ),
            self.sayRecog(),

            ### Mutter
            #############################
            self.mutter(),

            ### Chatterbox
            #############################
            self.chat(),
            policy=PARALLEL_SUCCESS.REQUIRE.ALL)
        return visit(tree, blackboard=self.bb)
Example #10
0
    def buildTree(self):
        """Build the behavior tree.

        Building the behavior tree is as simple as nesting the
        behavior constructor calls.

        Building the Behavior Tree
        ==========================

         We'll use a L{parallel<owyl.core.parallel>} parent node as
         the root of our tree. Parallel is essentially a round-robin
         scheduler. That is, it will run one step on each its children
         sequentially, so that the children execute parallel to each
         other. Parallel is useful as a root behavior when we want
         multiple behaviors to run at the same time, as with Boids.

         The first call to a task node constructor returns another
         function. Calling I{that} function will return an iterable
         generator. (This behavior is provided by the "@task..."
         family of python decorators found in L{owyl.core}.)
         Generally, you won't have to worry about this unless you're
         writing new parent nodes, but keep it in mind.

         Also note that keyword arguments can be provided at
         construction time (call to task constructor) or at run-time
         (call to visit). The C{blackboard} keyword argument to
         C{visit} will be available to the entire tree. (This is also
         why all nodes should accept C{**kwargs}-style keyword
         arguments, and access.

         Skipping down to the end of the tree definition, we see the
         first use of
         L{visit<owyl.core.visit>}. L{visit<owyl.core.visit>} provides
         the external iterator interface to the tree. Technically,
         it's an implementation of the Visitor pattern. It visits each
         "node" of the behavior tree and iterates over it, descending
         into children as determined by the logic of the parent
         nodes. (In AI terminology, this is a depth-first search, but
         with the search logic embedded in the tree.)
         L{visit<owyl.core.visit>} is also used internally by several
         parent behaviors, including L{parallel<owyl.core.parallel>},
         L{limit<owyl.decorators.limit>}, and
         L{repeatAlways<owyl.decorators.repeatAlways>} in order to
         gain more control over its children.

        L{limit<owyl.decorators.limit>}
        ===============================

         The next parent node we see is
         L{limit<owyl.decorators.limit>}. L{limit<owyl.decorators.limit>}
         is a decorator node designed to limit how often its child is
         run (given by the keyword argument C{limit_period} in
         seconds). This is useful for limiting the execution of
         expensive tasks.

         In the example below, we're using
         L{limit<owyl.decorators.limit>} to clear memoes once every
         0.4 seconds. This implementation of Boids uses
         L{memojito<examples.memojito>} to cache (or "memoize")
         neighbor data for each Boid. Neighbor data is used by each of
         the core behaviors, and is fairly expensive to
         calculate. However, it's constantly changing, so adjusting
         the limit_period will affect the behavior of the flock (and
         the frame rate).

        L{repeatAlways<owyl.decorators.repeatAlways>}
        =============================================

         We next see the L{repeatAlways<owyl.decorators.repeatAlways>}
         decorator node. This does exactly as you might expect: it
         takes a behavior that might only run once, and repeats it
         perpetually, ignoring return values and always yielding None
         (the special code for "I'm not done yet, give me another
         chance to run").

        L{sequence<owyl.decorators.sequence>}
        =============================================

         Runs a sequence of actions. If any action yields False,
         then the rest of the sequence is not executed (the sequence
         is halted).  Otherwise, the next sequence item is run.  In
         this example, a boid accelerates away only if it is too close
         to another boid.

        Core Behaviors
        ==============

         The core behaviors are documented below in each method's
         docstring. They are:

          - L{Boid.hasCloseNeighbors}: conditional to detect crowding
          - L{Boid.accelerate}: accelerate at a given rate
          - L{Boid.matchSpeed}: accelerate to match a given speed
          - L{Boid.move}: move straight ahead at current speed
          - L{Boid.seek}: seek a fixed goal position
          - L{Boid.steerToMatchHeading}: match neighbors' average
            heading
          - L{Boid.steerForSeparation}: steer away from close
            flockmates
          - L{Boid.steerForCohesion}: steer toward average position of
            neighbors.

        """
        tree = owyl.parallel(
            owyl.limit(owyl.repeatAlways(self.clearMemoes(), debug=True),
                       limit_period=0.4),

            ### Velocity and Acceleration
            #############################
            owyl.repeatAlways(
                owyl.sequence(
                    self.hasCloseNeighbors(),
                    self.accelerate(rate=-.01),
                ), ),
            self.move(),
            self.matchSpeed(match_speed=300, rate=.01),

            ### Steering
            ############
            self.seek(goal=(0, 0), rate=5),
            self.steerToMatchHeading(rate=2),
            self.steerForSeparation(rate=5),
            self.steerForCohesion(rate=2),
            policy=owyl.PARALLEL_SUCCESS.REQUIRE_ALL)
        return owyl.visit(tree, blackboard=self.bb)
Example #11
0
    def buildTree(self):
        """Build the behavior tree.

        Building the behavior tree is as simple as nesting the
        behavior constructor calls.

        Building the Behavior Tree
        ==========================

         We'll use a L{parallel<owyl.core.parallel>} parent node as
         the root of our tree. Parallel is essentially a round-robin
         scheduler. That is, it will run one step on each its children
         sequentially, so that the children execute parallel to each
         other. Parallel is useful as a root behavior when we want
         multiple behaviors to run at teh same time, as with Boids.

         The first call to a task node constructor returns another
         function. Calling I{that} function will return an iterable
         generator. (This behavior is provided by the "@task..."
         family of python decorators found in L{owyl.core}.)
         Generally, you won't have to worry about this unless you're
         writing new parent nodes, but keep it in mind.

         Also note that keyword arguments can be provided at
         construction time (call to task constructor) or at run-time
         (call to visit). The C{blackboard} keyword argument to
         C{visit} will be available to the entire tree. (This is also
         why all nodes should accept C{**kwargs}-style keyword
         arguments, and access 

         Skipping down to the end of the tree definition, we see the
         first use of
         L{visit<owyl.core.visit>}. L{visit<owyl.core.visit>} provides
         the external iterator interface to the tree. Technically,
         it's an implementation of the Visitor pattern. It visits each
         "node" of the behavior tree and iterates over it, descending
         into children as determined by the logic of the parent
         nodes. (In AI terminology, this is a depth-first search, but
         with the search logic embedded in the tree.)
         L{visit<owyl.core.visit>} is also used internally by several
         parent behaviors, including L{parallel<owyl.core.parallel>},
         L{limit<owyl.decorators.limit>}, and
         L{repeatAlways<owyl.decorators.repeatAlways>} in order to
         gain more control over its children.

        L{limit<owyl.decorators.limit>}
        ===============================

         The next parent node we see is
         L{limit<owyl.decorators.limit>}. L{limit<owyl.decorators.limit>}
         is a decorator node designed to limit how often its child is
         run (given by the keyword argument C{limit_period} in
         seconds). This is useful for limiting the execution of
         expensive tasks.

         In the example below, we're using
         L{limit<owyl.decorators.limit>} to clear memoes once every
         second. This implementation of Boids uses
         L{memojito<examples.memojito>} to cache (or "memoize")
         neighbor data for each Boid. Neighbor data is used by each of
         the core behaviors, and is fairly expensive to
         calculate. However, it's constantly changing, so adjusting
         the limit_period will affect the behavior of the flock (and
         the frame rate).

        L{repeatAlways<owyl.decorators.repeatAlways>}
        =============================================
        
         We next see the L{repeatAlways<owyl.decorators.repeatAlways>}
         decorator node. This does exactly as you might expect: it
         takes a behavior that might only run once, and repeats it
         perpetually, ignoring return values and always yielding None
         (the special code for "I'm not done yet, give me another
         chance to run").

        Core Behaviors
        ==============

         The core behaviors are documented below in each method's
         docstring. They are:

          - L{Boid.hasCloseNeighbors}: conditional to detect crowding
          - L{Boid.accelerate}: accelerate at a given rate
          - L{Boid.matchSpeed}: accelerate to match a given speed
          - L{Boid.move}: move straight ahead at current speed
          - L{Boid.seek}: seek a fixed goal position
          - L{Boid.steerToMatchHeading}: match neighbors' average
            heading
          - L{Boid.steerForSeparation}: steer away from close
            flockmates
          - L{Boid.steerForCohesion}: steer toward average position of
            neighbors.

        """
        tree = owyl.parallel(
            owyl.limit(
                owyl.repeatAlways(self.clearMemoes(), debug=True), 
                limit_period=0.4),
                        
            ### Velocity and Acceleration
            #############################
            owyl.repeatAlways(owyl.sequence(self.hasCloseNeighbors(),
                                            self.accelerate(rate=-.01),
                                            ),
                              ),
            self.move(),
            self.matchSpeed(match_speed=300, rate=.01),

            ### Steering
            ############
            self.seek(goal=(0, 0), rate=5),
            self.steerToMatchHeading(rate=2),
            self.steerForSeparation(rate=5),
            self.steerForCohesion(rate=2),

            policy=owyl.PARALLEL_SUCCESS.REQUIRE_ALL
            )
        return owyl.visit(tree, blackboard=self.bb)
Example #12
0
    def makeBasicZenoTree(self):
        ## Zeno's Body Paint subtree
        zenoBodyPaint = \
            owyl.selector(
                owyl.sequence(
                    self.isNotSameBrushStroke(),
                    self.isGreater(num1=self.animationOutputDur, num2=2),
                    self.setVariable(var=self.actionName, value="BrushStrokeGesture"),
                    owyl.selector(  # try the action sequence (subtree) or report failure
                        owyl.sequence(
                            owyl.visit(self.announceAndResetTree, blackboard=self.blackboard),
                            self.showAction(action=self.actionName, part=self.HEAD_NECK)  # Finally play the action's animation
                        ),
                        owyl.sequence(
                            self.say(utterance="I'm not feeling inspired today..."),
                            owyl.fail()
                        )
                    )
                ),
                owyl.sequence(
                    self.setVariable(var=self.actionName, value="Idle"),
                    owyl.selector(  # try the command sequence (subtree) or report failure
                        owyl.sequence(
                            owyl.visit(self.announceAndResetTree, blackboard=self.blackboard),
                            self.showAction(action=self.actionName, part=self.HEAD_NECK)  # Finally play the action's animation
                        ),
                        owyl.sequence(
                            self.say(utterance="Why can't I stand?"),
                            owyl.fail()
                        )
                    )
                )
            )

        ## body behavior subtree
        zenoBodySubtree = \
            owyl.limit(
                owyl.repeatAlways(
                    owyl.selector(  # Select response to command or natural behavior
                        owyl.sequence(  # If the last audio or blender input is a command, then select a response
                            self.isCommand(commandName=self.commandName),
                            self.setVariable(var=self.bodyOrFace, value=self.UPPER_BODY),
                            owyl.visit(self.selectBasicCommandSubtree, blackboard=self.blackboard)
                        ),
                        # It's not a command, so start checking for natural behaviors
                        owyl.sequence(
                            # self.isNoSalientTarget(),
                            # self.isNoFaceTarget(),
                            # self.isNoAudioInput(),
                            # self.isNoRosInput(),
                            # self.isNoEmotionInput(),
                            self.isIdle(),
                            # There's nothing to do, so let's paint!
                            owyl.visit(zenoBodyPaint, blackboard=self.blackboard)
                        ),
                        owyl.sequence(
                            # TODO: the other natural actions, once we have a saliency target, etc.
                        )
                    )
                ),
                limit_period=0.4  # Yield to the other behaviors after every 400 milliseconds of processing
            )

        # face & neck behavior subtree
        zenoFaceSubtree = \
            owyl.limit(
                owyl.repeatAlways(
                    owyl.selector(  # Select from one of several mutually exclusive face & neck behaviors
                        owyl.sequence(  # If the last audio or blender input is a command, then select a response
                            self.isCommand(commandName=self.commandName),
                            self.setVariable(var=self.bodyOrFace, value=self.HEAD_NECK),
                            owyl.visit(self.selectBasicCommandSubtree, blackboard=self.blackboard)
                        ),
                        owyl.sequence(
                            # self.isSalientTarget(),
                            # self.isNoFaceTarget(),
                            # self.isNoAudioInput(),
                            # self.isNoRosInput(),
                            # self.isNoEmotionInput(),
                            self.isIdle(),
                            owyl.visit(self.faceGaze, blackboard=self.blackboard)
                        ),
                        owyl.sequence(
                            self.isFaceTarget()
                        )
                    )
                ),
                limit_period=0.4  # Yield to the other behaviors after every 400 milliseconds of processing
            )

        # Zeno's root tree
        zenoTree = \
            owyl.parallel(  # At the highest level, run several parallel behaviors
                owyl.visit(zenoBodySubtree, blackboard=self.blackboard),
                owyl.visit(zenoFaceSubtree, blackboard=self.blackboard),
                owyl.limit(
                    owyl.repeatAlways(
                        owyl.sequence(
                            # Poll for input coming from blender, for example buttons to stop movement, etc.
                            # May move this logic out of the behavior tree...
                            # self.pollForBlenderInput(),

                            # Listen for audio input from people talking, etc.
                            # Again, this might not be the best place for this...
                            # self.listenForAudioInput()
                        )
                    ),
                    limit_period=0.4  # Yield to the other behaviors after every 400 milliseconds of processing
                ),
                policy=owyl.PARALLEL_SUCCESS.REQUIRE_ALL
            )
        return owyl.visit(zenoTree, blackboard=self.blackboard)
Example #13
0
    def makeBasicZoidSteinTree(self):
        ## The scripted dance of ZoidStein, used when no faces or salient targets are detected.
        # Assumes body state has been reset to starting state
        zoidSteinBodyDance = \
            owyl.sequence(
                self.showCommand(commandName="WalkForward", part=self.LOWER_BODY),
                self.showCommand(commandName="WalkBackward", part=self.LOWER_BODY),
                self.showAction(commandName="PointUp", part=self.UPPER_BODY),
                self.showAction(commandName="PointDown", part=self.UPPER_BODY)
            )

        ## body behavior subtree
        # TODO: Attach subtrees properly
        zoidSteinBodySubtree = \
            owyl.limit(
                owyl.repeatAlways(
                    owyl.selector(  # Select response to command or natural behavior
                        owyl.sequence(  # If the last audio or blender input is a command, then select a response
                            self.isCommand(commandName=self.commandName),
                            self.setVariable(var=self.bodyOrFace, value="body"),
                            owyl.visit(self.selectBasicCommandSubtree, blackboard=self.blackboard)
                        ),
                        # It's not a command, so start checking for natural behaviors
                        owyl.sequence(
                            # self.isNoSalientTarget(),
                            # self.isNoFaceTarget(),
                            # self.isNoAudioInput(),
                            # self.isNoRosInput(),
                            # self.isNoEmotionInput(),
                            self.isIdle(),
                            # There's nothing to do, so let's dance!
                            owyl.visit(zoidSteinBodyDance, blackboard=self.blackboard)
                        ),
                        owyl.sequence(
                            #TODO: the other natural actions, once we have a saliency target, etc.
                        )
                    )
                ),
                limit_period=0.4  # Yield to the other behaviors after every 400 milliseconds of processing
            )

        ## face & neck behavior subtree
        # TODO: Attach subtrees properly
        zoidSteinFaceSubtree = \
            owyl.limit(
                owyl.repeatAlways(
                    owyl.selector(  # Select from one of several mutually exclusive face & neck behaviors
                        owyl.sequence(  # If the last audio or blender input is a command, then select a response
                            self.isCommand(commandName=self.commandName),
                            self.setVariable(var=self.bodyOrFace, value=self.HEAD_NECK),
                            owyl.visit(self.selectBasicCommandSubtree, blackboard=self.blackboard)
                        ),
                        owyl.sequence(
                            # self.isSalientTarget(),
                            # self.isNoFaceTarget(),
                            # self.isNoAudioInput(),
                            # self.isNoRosInput(),
                            # self.isNoEmotionInput(),
                            self.isIdle(),
                            owyl.visit(self.faceGaze, blackboard=self.blackboard)
                        ),
                        owyl.sequence(
                            self.isFaceTarget(),
                        )
                    )
                ),
                limit_period=0.4  # Yield to the other behaviors after every 400 milliseconds of processing
            )

        ## ZoidStein's root tree
        zoidSteinTree = \
            owyl.parallel(  # At the highest level, run several parallel behaviors
                owyl.visit(zoidSteinBodySubtree, blackboard=self.blackboard),
                owyl.visit(zoidSteinFaceSubtree, blackboard=self.blackboard),
                owyl.limit(
                    owyl.repeatAlways(
                        owyl.sequence(
                            # Poll for input coming from blender, for example buttons to stop movement, etc.
                            # May move this logic out of the behavior tree...
                            # self.pollForBlenderInput(),

                            # Listen for audio input from people talking, etc.
                            # Again, this might not be the best place for this...
                            # self.listenForAudioInput()
                        )
                    ),
                    limit_period=0.4  # Yield to the other behaviors after every 400 milliseconds of processing
                ),
                policy=owyl.PARALLEL_SUCCESS.REQUIRE_ALL
            )

        return owyl.visit(zoidSteinTree, blackboard=self.blackboard)
Example #14
0
    def makeBasicTree(self):
        robotTree = \
            owyl.parallel(
                ######################################## BodySubtree ########################################
                owyl.limit(
                    owyl.repeatAlways(
                        owyl.sequence(
                            self.updateFrontVariables(),
                            self.determineCurrentTarget(),
                            self.removeFace(),
                            owyl.selector(
                                # Gaze at face targets
                                owyl.sequence(
                                    self.isFaceTarget(),
                                    self.isNoSalientTarget(),
                                    self.isNoAudioInput(),
                                    self.isNoRosInput(),
                                    self.isNoEmotionInput(),
                                    self.faceGaze()
                                ),

                                # Gaze at salient targets
                                # owyl.sequence(
                                #     self.isSalientTarget(),
                                #     # self.isNoFaceTarget(),
                                #     self.isNoAudioInput(),
                                #     self.isNoRosInput(),
                                #     self.isNoEmotionInput(),
                                #     self.faceGaze()
                                # ),

                                # Handle commands
                                owyl.sequence(
                                    owyl.selector(
                                        self.isAudioInput(),
                                        self.isRosInput()
                                    ),
                                    owyl.selector(
                                        self.isCommand(key="audioInput"),
                                        self.isCommand(key="rosInput")
                                    ),
                                    owyl.selector(
                                        owyl.sequence(
                                            owyl.selector(
                                                self.isCommandPhrase(commandName="StopSpeech", actionPhrase="actionName"),
                                                self.isCommandPhrase(commandName="WalkForward", actionPhrase="actionName"),
                                                self.isCommandPhrase(commandName="WalkBackward", actionPhrase="actionName"),
                                                self.isCommandPhrase(commandName="TurnLeft", actionPhrase="actionName"),
                                                self.isCommandPhrase(commandName="TurnRight", actionPhrase="actionName"),
                                                self.isCommandPhrase(commandName="StopSpeaking", actionPhrase="actionName"),
                                                self.isCommandPhrase(commandName="Smile", actionPhrase="actionName"),
                                                self.isCommandPhrase(commandName="Frown", actionPhrase="actionName"),
                                                # self.isCommandPhrase(commandName="FrownMouth", actionPhrase="actionName"),
                                                self.isCommandPhrase(commandName="Surprise", actionPhrase="actionName"),
                                                self.isCommandPhrase(commandName="TakeThis", actionPhrase="actionName"),
                                                self.isCommandPhrase(commandName="GiveBack", actionPhrase="actionName"),
                                                self.isCommandPhrase(commandName="Wave", actionPhrase="actionName"),
                                            ),
                                            self.isNotSpeaking(),
                                            # self.sayStartAction(key="actionName"),
                                            self.showAction(key="actionName")
                                        ),
                                        self.printStatus(msg="I'm sorry, Dave, I'm afraid I can't do that...")
                                    )
                                ),

                                # Play emotion detection game
                                owyl.sequence(
                                    owyl.selector(  #TODO: change to sequence
                                        self.isAudioInput(),
                                        self.isEmotionInput(),
                                    ),
                                    self.isNotStopEmotionDetection(key="audioInput"),
                                    self.isEmotionDetection(key="audioInput"),
                                    self.isNotSpeaking(),
                                    self.startEmotionDetection(),
                                ),

                                # Play object recognition game
                                owyl.sequence(
                                    owyl.selector(
                                        self.isAudioInput(),
                                        self.isObjInput(),
                                    ),
                                    self.isNotStopObjRecognition(key="audioInput"),
                                    self.isObjRecognition(key="audioInput"),
                                    self.isNotSpeaking(),
                                    self.startObjRecognition()
                                ),

                                # Send to the dialogue system
                                owyl.sequence(
                                    self.isAudioInput(),
                                    self.isNotSpeaking(),
                                    self.toZenoDial(key="audioInput")
                                )
                            )
                        )
                    ),
                    limit_period=0.001
                ),

                ######################################## General tree ########################################
                owyl.limit(
                    owyl.repeatAlways(
                        owyl.sequence(
                            self.test(),
                            self.updateVariables()
                        )
                    ),
                    limit_period=0.001
                ),
                policy=owyl.PARALLEL_SUCCESS.REQUIRE_ALL
            )
        return owyl.visit(robotTree, blackboard=self.blackboard)