Is anyone using Behavior Trees with their robot?

1,797 views
Skip to first unread message

Patrick Goebel

unread,
Feb 10, 2016, 4:26:09 PM2/10/16
to ros-by-example
Hello ROS Fans,

As some of you know, Volume 2 in the ROS By Example series includes a
chapter on using Behavior Trees for controlling robot behavior. I am
curious to know if anyone is using Behavior Trees with their own robot
and if so, what kinds of things are you doing with it?

I am experimenting more with Behavior Trees myself and I am adding some
new tasks and features to the pi_trees library that I will release after
some more testing. But first I'd like to find out what kind of
experience others are having using behavior trees with their own projects.

Thanks!
patrick

--
The Pi Robot Project
http://www.pirobot.org/wordpress


Rud Merriam

unread,
Feb 10, 2016, 11:44:38 PM2/10/16
to ros-by-...@googlegroups.com
I've looked at the BTs and even started implementing my own version in C++ but have been distracted by other activities so haven't used them. But I'd like to share my use of subsumption in my NASA SRR rovers.

I suspect my use was not strictly subsumption but close. I processed a list of behaviors passing in a boolean preempted argument. If a behavior fired then preempted was set to true. The behaviors after that were not to invoke actions but they could record information, like the passage of time for a countdown. Pretty standard, actually.

The main change was I kept a number of lists of behaviors called tasks. One behavior implemented switching of tasks. For example, in the competition one of the first actions is to leave the starting area (platform). That is simply driving ahead and given the location of the starting area it was clear of obstacles. Therefore there was no need to check for them using the vision processing. The next step did involve vision processing to check for the orientation of the rover against some landmarks. But it was a stationary task so all the obstacle detection or movement behaviors were not needed. Once the "drive off platform" task was completed the "check position" task was swapped in. After it completed a "search for samples" task began, etc.

One of the problems with large subsumption systems is they can get fragile. If you've got 150 behaviors in a list you're bound to break something when you add in another behavior. By keeping my subsumption lists small it avoided that problem, or at least localized it to a few specific tasks making finding it easier.

I was also use RoboRealm for vision processing. Each task had its own RR pipeline which got swapped in with the task. Again, that reduced the fragility problem.

Overall it kept the processing cycle short since only the necessary behaviors were on the list.

You might want to consider something similar for BTs.

Peter Heim

unread,
Feb 11, 2016, 6:37:08 AM2/11/16
to ros-by-example
Hi Patrick
I'm using behaviour trees to monitor the battery and auto dock when the battery is low the behaviour tree also handles navigation and head movements request from the AI system. I have also incorporated a basic emotion system into Robbie , if the robot hasn't done anything for a while he get bored and dose a random thing. I tried a new project where the robot goes through a routine navigate to a location ,do a speech then move the arms with moveit then move to the next location and do more of the same. I had a lot of trouble using behaviour trees with the transitions. I rewrote it with smach and with the help of the smach viewer it worked in a very short time  mainly because I could see the states and the transitions but for a more complex it looks a real mess it would be better if you could move the boxes around to make the flow clearer. I have also tried Flexbe and it shows a lot of promise but lacks documentation. For the next project I would like to add more tasks like face recognition,  grasping object tracking. I also like the explicit transition from smach, unless I'm doing something wrong it harder with behaviour trees.
could be a good title for a book "Pi_trees by example"

Regards
Peter   

Patrick Goebel

unread,
Feb 11, 2016, 10:21:51 AM2/11/16
to ros-by-...@googlegroups.com
Hi Rud,

Many thanks for sharing your experience.  I was part of a team that also entered the NASA SRRC last year but we started our project fairly late and did not get a chance to fully flesh out a software architecture for managing the robot's tasks.  Like you say, once the number of tasks or behaviors gets large, keeping track of the interactions and possible failure modes can get difficult.  In theory, behavior trees should be good at building a modular task hierarchy that can automatically fall back on recovery behaviors using Selectors and Decorators.  I'm not working on the SRRC this year but might try a kind of indoor version in my living room using behavior trees and a Kobuki (Turtlebot 2).

--patrick


-- 
The Pi Robot Project
http://www.pirobot.org/wordpress

Patrick Goebel

unread,
Feb 11, 2016, 6:30:12 PM2/11/16
to ros-by-...@googlegroups.com
Hi Peter,

That sounds very cool.  Coincidentally, I am testing a navigation/autodocking behavior tree myself as we speak.  I'm using a Kobuki (Turtlebot 2) that has a very nice autodocking ability that seems to work quite well.

I agree that being able to visualize the behavior tree is essential.  I am working on getting someone to program a real-time BT viewer similar to the smach viewer and I will post back to the list if/when it gets done.

Thanks for pointing out Flexbe which looks very interesting.  I'm wondering how hard it would be to adapt the code to behavior trees...In the Windows and MacOS X worlds, there is Unity and the Behavior Designer module that makes it incredibly easy to create complex behavior trees.  We need something like that for Ubuntu...

--patrick

-- 
The Pi Robot Project
http://www.pirobot.org/wordpress


Patrick Goebel

unread,
Feb 16, 2016, 9:43:11 AM2/16/16
to ros-by-...@googlegroups.com
I discovered that the Unity game engine now runs on Linux.  It's not yet 100% stable and crashes once in awhile so you have to save your work often.  I also installed the Behavior Designer plug-in (or "asset" as it is called on Unity).  This cost $75 but was well worth it.

The Behavior Designer allowed me to simulate a simple robot patrol while monitoring battery levels and returning to the docking station when needing a recharge.  Once I could see my behavior tree this way, I immediately uncovered errors in my logic and was able to fix them quickly.  Here is a screen shot of the Behavior Designer illustrating the simulated patrol:




Sequences are represented by the icons with an arrow, selectors are indicated by a ? mark and the clock icons represent a timer that I am using to simulate the navigation tasks.

Note that the top level Behave task is a sequence so as we go from left to right in the first row, if any task fails, tasks further to the right will not be executed.  This is the way behavior trees handle task priority.

Reading the tree from top to bottom and left to right, the first row starts with the Get Diagnostics task that on the real robot subscribes to the /diagnostics_agg topic and gets the latest diagnostic values such as battery level, charging status, etc.  The data obtained are written to the global blackboard so that other tasks in the tree can access them.  This task always returns SUCCESS so that the Behave sequence advances to the right and runs the Stay Healthy selector.

The Stay Healthy selector first runs the Check Charge selector which in turn fires the Charge Status sequence.  The Charge Status sequence first runs the Charging? check to see if the robot is already charging.  If so, the sequence runs the Charging Complete? check.  This task returns a status of RUNNING if the charging is not yet complete.  The RUNNING status propagates  up to the Charge Status sequence which causes the Check Charge selector to hold off running the Battery Check task.  Since the Check Charge selector is still RUNNING, so too is its parent, the Stay Healthy selector, so the tree essentially loops between the Get Diagnostics task and the Stay Healthy selector until charging completes.

If the robot is not already charging, the Charging? check returns FAILURE which means the Charge Status sequence also fails and the Check Charge selector runs the Battery Check task.  If the robot's battery level is below a set threshold (for example 20%), then the Battery Check task returns FAILURE which means the Check Charge selector also returns FAILURE and the Stay Healthy selector executes the Recharge sequence.  The Recharge sequence first runs the Nav Near Dock tasks which uses move_base to send the robot to a location in front of the docking station, then it calls the Kobuki's Auto Dock action which takes the robot the rest of the way onto the charging station.

If the battery levels are OK, then the Battery Check task returns SUCCESS and so does the Stay Healthy selector.  This allows the Behave sequence to move to the next child task on the right which is the Get Off Dock selector.  The Kobuki docking station is designed in such a way that the robot needs to back off a few inches before it can safely rotate and move away.  So the Get Off Dock selector first runs the Off Dock? check to see if the robot is already off the dock and if not, it runs the Back Up task which moves the robot backward for about 5 seconds.  On the next tick of the tree, the Off Dock? check will return SUCCESS so the Get Off Dock selector is happy and control continues to the Loop Patrol task.

The Loop Patrol tasks continues to run its Nav Location tasks until something earlier in the tree changes.  In this case, the most likely event is that the battery runs low so that the Recharge task will kick in and send the robot back to the docking station.

Here are a couple of other representations of the tree I am using.  I have updated pi_trees_lib so that the print_tree() function now takes an argument "use_symbols" which is False by default for backwards compatibility.  If you use print_tree(BEHAVE, use_symbols=True) after building your tree, you'll see an output similar to the following:

 --> BEHAVE
     --| GET_DIAGNOSTICS
     --? STAY_HEALTHY
         --? CHECK_CHARGE
             --> CHARGE_STATUS
                 --| CHECK_CHARGING
                 --| CHECK_CHARGE_COMPLETE
             --| CHECK_BATTERY_OK
         --> RECHARGE
             --| NAV_NEAR_DOCK
             --| AUTO_DOCK
     --? GET_OFF_DOCK
         --| CHECK_OFF_DOCK
         --| UNDOCK
     <-> LOOP_PATROL
         --> PATROL
             --| MOVE_BASE_TASK_0
             --| MOVE_BASE_TASK_1
             --| MOVE_BASE_TASK_2
             --| MOVE_BASE_TASK_3
             --| MOVE_BASE_TASK_4

The key for the symbols is as follows:

--> Sequence or Iterator
--? Selector
--| Task or Condition
<-> Loop

I was also able to generate a DOT version of the graph which can be viewed with xdot and it looks like the following.



--patrick


-- 
The Pi Robot Project
http://www.pirobot.org/wordpress


On 02/11/2016 03:37 AM, Peter Heim wrote:

Patrick Goebel

unread,
Feb 17, 2016, 10:12:21 AM2/17/16
to ros-by-...@googlegroups.com
Hi Peter,

Would it be possible for you to post a screen shot of your SMACH machine as viewed in the smach_viewer?  As I add tasks to Pi Robot's behavior tree, I am curious to see how the task diagrams compare for readability.

I just now added a new subtree which enables the robot to respond to a manual docking request that will interrupt the patrol and send Pi back to the docking station.  Here's how the new tree looks (larger image attached):



Note how there is no need to modify the rest of the tree when adding this behavior.  Other manual requests could also be added under the "Manual Requests" branch.  Also, if it was decided that the Stay Healthy subtree should have a higher priority than the Manual Requests subtree, the order of the two branches would just be swapped.

--patrick


-- 
The Pi Robot Project
http://www.pirobot.org/wordpress


On 02/11/2016 03:37 AM, Peter Heim wrote:
Screenshot from 2016-02-17 07:07:37.png

Peter Heim

unread,
Feb 17, 2016, 4:18:46 PM2/17/16
to ros-by-example
Hi Patrick
I have attached a screen shot of show time there is no stay healthy in as yet but auto dock works. Auto dock is handled by the arduino so we only have to send a message for it to work. The node intro_tasks (top Left) uses moveit to move the arms I still have to add more talking to this node but all other node will look like this

I have been rewriting this with behaviour trees but its slow going 

Regards
Peter 
Screenshot from 2016-02-18 06:42:09.png

Patrick Goebel

unread,
Feb 17, 2016, 10:30:32 PM2/17/16
to ros-by-...@googlegroups.com
Hi Peter,

This is great--many thanks for sharing!  One nice thing about state machines and the SMACH viewer is that it makes the transitions quite explicit, something that is only implied in a behavior tree.  So the behavior tree appears tidier on the surface but it takes more practice to be able to read it.

I'll post the Python code for my own behavior tree once I clean it up a bit.


--patrick

-- 
The Pi Robot Project
http://www.pirobot.org/wordpress

Peter Heim

unread,
Feb 17, 2016, 11:02:22 PM2/17/16
to ros-by-example
Hi Patrick
It's good to see the state changes happen. With BT's if i use a long sequence  like

SHOWTIME = Sequence("SHOWTIME",[NAV_INTRO, PRINT_MESSAGE, PRINT_MESSAGE1, NAV_LEFT, NAV_CENTER, NAV_RIGHT, NAV_CENTER2, NAV_AUTODOCK, SET_VARIABLE])
 
the NAV_ are actionstate navigation  reset after false
PRINT_MESSAGE just prints a message 
when this runs after every nav stage the messages print 
I dont really understand how the flow works it should go from left to right  this will go NAV_INTRO, PRINT_MESSAGE, PRINT_MESSAGE then NAV_INTRO, PRINT_MESSAGE, PRINT_MESSAGE NAV_LEFT, and so on 
I may have to break it in to smaller tasks what are your thoughts on the matter?

Peter

Patrick Goebel

unread,
Feb 18, 2016, 12:16:00 AM2/18/16
to ros-by-...@googlegroups.com
Hi Peter,

The issue here is that the entire sequence is executed on every "tick" of the behavior tree.  Near the bottom of your script you probably have a loop similar to:

while not rospy.is_shutdown():
    BEHAVE.run()
    rospy.sleep(0.1)


This loop ensures that the entire tree is reevaluated on every tick so that if the status of one of the nodes changes, the behavior tree will react accordingly.

So to get your messages to print only once for each successful pass through the sequence, you need to define the print tasks in such a way that they will print the first time but not again until they are reset.  Here is a DisplayMessage task that would do the job.  Put this class anywhere in your script outside of the main class:

class DisplayMessage(Task):
    def __init__(self, name, message):
        super(DisplayMessage, self).__init__(name)
       
        self.name = name
        self.message = message
 
    def run(self):
        if self.status != TaskStatus.SUCCESS:
            rospy.loginfo(self.message)
            self.status = TaskStatus.SUCCESS
               
        return self.status
   
    def reset(self):
        self.status = None


So to print the message "Greetings Humans!" where you have your PRINT_MESSAGE task, you would make the assignment:

PRINT_MESSAGE = DisplayMessage("PRINT_MESSAGE", "Greetings Humans!")

Then define your PRINT_MESSAGE1 task in a similar way.

Next, we need to use the reset_after flag on the entire sequence.  This is a new feature in pi_trees for sequences as a whole so you will need to get the latest updates from the pi_trees repository:

$ roscd pi_trees
$ git pull
$ git checkout indigo-devel


Note that you may need the following prerequisite with the latest version of pi_trees:

# sudo apt-get install python-pygraphviz

You can now add the reset_after=True to the sequence as a whole like this:

SHOWTIME = Sequence("SHOWTIME",[NAV_INTRO, PRINT_MESSAGE, PRINT_MESSAGE1, NAV_LEFT, NAV_CENTER, NAV_RIGHT, NAV_CENTER2, NAV_AUTODOCK, SET_VARIABLE], reset_after=True)

If you set reset_after=False for the whole sequence, then the sequence it will only ever run once no matter how many times you tick through the tree.


--patrick

-- 
The Pi Robot Project
http://www.pirobot.org/wordpress


Peter Heim

unread,
Feb 18, 2016, 6:50:06 AM2/18/16
to ros-by-example
Hi Patrick
Thanks for that it works a treat now
here is what the BT looks like now
MCP Tree
 --> BEHAVE
     --> STAY_HEALTHY
         --? BATTERY
             --| CHECK_BATTERY
             --> RECHARGE
                 --| NAV_DOCK_TASK
                 --| AUTODOCK_
         --? SERVO
             --| CHECK_SERVO
             --> RECHARGE
                 --| NAV_DOCK_TASK
                 --| AUTODOCK_
         --? MOTOR
             --| CHECK_MOTOR
             --> RECHARGE
                 --| NAV_DOCK_TASK
                 --| AUTODOCK_
     --> DEMO
         --? START
             --| START_DEMO
             --> SHOWTIME
                 --| NAV_INTRO
                 --| PRINT_MESSAGE
                 --| PRINT_MESSAGE1
                 --| NAV_LEFT
                 --| NAV_CENTER
                 --| NAV_RIGHT
                 --| NAV_CENTER2
                 --| NAV_AUTODOCK
                 --| SET_VARIABLE
     --> EMOTIONS
         --> EMOTION_SYS
             --| Timer
             --| PRINT_EMOTION
             --| Emotion1


Still a few place holder that need to be fleshed out. Next I want to add face tracking with face recognition and a inter active talk on a node thats call every ! minute 

I would like to see how complex the BT can be made and still be stable, and how to control the running of the nodes from a external program at the moment I use topics
and a dictionary in a external file the emotion system reads the current state form a external file

Peter 

Patrick Goebel

unread,
Feb 18, 2016, 10:12:02 PM2/18/16
to ros-by-...@googlegroups.com
Hi Peter,

That looks great!  Glad to hear it's working as expected now.  Still working on some bugs in my own tree...

--patrick
--
You received this message because you are subscribed to the Google Groups "ros-by-example" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ros-by-exampl...@googlegroups.com.
Visit this group at https://groups.google.com/group/ros-by-example.
For more options, visit https://groups.google.com/d/optout.

Peter Heim

unread,
Feb 18, 2016, 11:25:23 PM2/18/16
to ros-by-example
Hi Patrick 
How did you get that xdot graph of your behaviour tree?


Peter 

Patrick Goebel

unread,
Feb 19, 2016, 2:52:44 PM2/19/16
to ros-by-...@googlegroups.com
Hi Peter,

First, place the statement

        print_dot_tree(BEHAVE)

just before your loop that runs your tree.  You could put it right after the statement

        print_tree(BEHAVE, use_symbols=True)

When you run your script, the print_dot_tree() function will create a DOT file called tree.dot under your ~/.ros directory.

To view the file, install the xdot package:

$ sudo apt-get install xdot

Then try the command:

$ xdot ~/.ros/tree.dot

--patrick


-- 
The Pi Robot Project
http://www.pirobot.org/wordpress

Peter Heim

unread,
Feb 19, 2016, 8:37:59 PM2/19/16
to ros-by-example
Hi Patrick
One issue I have found with charging branch is it will block all other tasks from being run. This is OK in a patrol bot,  but I have some tasks that can be run while on the charger (face tracking and the emotion system  etc) and some of the tasks should not be run while the robot is driving(face tracking) can behaviour trees logic handle this or do we have to set variable and the like?

Peter

Peter Heim

unread,
Feb 20, 2016, 2:36:19 AM2/20/16
to ros-by-example
I think I answered my own question I can use parallel trees (P1,P2) and a few variables to control the execution

Peter


 
tree.dot

Patrick Goebel

unread,
Feb 20, 2016, 10:30:59 AM2/20/16
to ros-by-...@googlegroups.com
Hi Peter,

Yes, that's the way I would go.

--patrick

Patrick Goebel

unread,
Feb 28, 2016, 10:36:33 PM2/28/16
to ros-by-...@googlegroups.com
Hi Peter,

I believe I had a bad bug in the ParallelOne and ParallelAll tasks such
that the child tasks were actually running one after the other rather
than in parallel. If you've been using parallel trees and are getting
unexpected results, the latest update to pi_trees should fix it.

--patrick

On 02/19/2016 11:36 PM, Peter Heim wrote:
Message has been deleted

Nick Qian

unread,
Aug 10, 2016, 11:39:06 PM8/10/16
to ros-by-example
Hi patrick,

why don't you submit the pi-trees as a official module to ROS? 
Nearly every robot need a BT except the mechanical arm(may simple state machine can satisfy its requirement). Also the BT code in the internet don't have ROS interfaces(to topics, servers) and also not very suitable to robot. Mainly for games.
I'm also looking into your code t see if I can adopt it in my robot to control all its behavior. I used to see the "owyl"(http://www.pygame.org/project-owyl-1004-.html) but I found its complex for me.
 
Nick Qian

在 2016年2月11日星期四 UTC+8上午5:26:09,Pi Robot写道:

Patrick Goebel

unread,
Aug 12, 2016, 6:50:25 PM8/12/16
to ros-by-...@googlegroups.com
Hi Nick,

I'm not sure I know what you mean by "an official module to ROS".  The pi_trees package is already a ROS package like SMACH.  Perhaps you mean a binary Debian package for Ubuntu?  If so, I simply haven't had time to convert the source tree to a binary package, but it is not very hard to install from source.

--patrick
--
You received this message because you are subscribed to the Google Groups "ros-by-example" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ros-by-exampl...@googlegroups.com.
Visit this group at https://groups.google.com/group/ros-by-example.
For more options, visit https://groups.google.com/d/optout.

Nick Qian

unread,
Aug 14, 2016, 10:48:06 PM8/14/16
to ros-by-example
Hi Patrick,

I was trying to search a python behavior tree for my robot project and I only found the "owyl". I got the "pi_trees" after reading your great book the "rbx2" then I feel this is what I need. yes I mean is that pi_trees can be easily found in the Debian package, or in the ros-gbp(https://github.com/ros-gbp) where we search packages, that will be great:-)
regarding your topic, I'm trying to do a robot for playing with children, just for their fun. So it cannot be too stupid. So beside the battery/mechnical check, it also perform face/object tracking, talking to them, following someone ...etc. I have a "ParallelOne" on the root, then a lot of selectors/sequences. 
During coding I have 3 questions:
1) Is it possible to add weight random selector? some behaviors need to be ran more times.
2) Is it more readable if adding random or weight random to selector/sequence by using python decorator?
3) I cannot understand the owyl code. which is easier to change the tree / adding new behavior? Sorry this may not be a good question:-)

Nick Qian 


在 2016年8月13日星期六 UTC+8上午6:50:25,Pi Robot写道:

Patrick Goebel

unread,
Aug 15, 2016, 10:21:02 PM8/15/16
to ros-by-...@googlegroups.com
Hi Nick,

Normally when I am looking to see if a ROS package exists for some task I just Google it. :-)  For example, Googling "ROS Behavior Trees" brings up several options including my own.

I also found the owyl project several years ago but decided the approach used there made it more difficult to create a ROS wrapper around it so I wrote my own behavior trees library.

Regarding your questions:
1) Is it possible to add weight random selector? some behaviors need to be ran more times.
This shouldn't be very hard to add.  For example, here is one idea how to do it.  If you know how to create a fork of the pi_trees repository on Github, you can add a weighted random selector and then submit a pull request for me to merge into my repository.

2) Is it more readable if adding random or weight random to selector/sequence by using python decorator?

Sorry, but I'm not sure what you mean.  The pi_trees library already contains the RandomSelector, RandomSequence, and RandomIterator behaviors.  But you would have to add weighted versions of these.


3) I cannot understand the owyl code. which is easier to change the tree / adding new behavior? Sorry this may not be a good question:-)

Can you give an example of what you want to do?

--patrick

Nick Qian

unread,
Aug 18, 2016, 5:56:01 AM8/18/16
to ros-by-example
Hi Patrick,

I already found the way to build the tree easily with pi_trees such as:
#------------------------------ L4 branch ...leafs
        CHARGE_ROBOT_TASK = ServiceTask("CHARGE_ROBOT", result_cb = self.recharge_cb)
        NAV_DOCK_TASK = SimpleActionTask("NAV_DOCK_TASK", MoveAction, goal, reset_after=True, feedback_cb=self.update_robot_position)

#------------------------------  L3 branch ... leafs & composites
        CHECK_BATTERY = MonitorTask("CHECK_BATTERY", "battert_level", Float32, self.check_battery)
        
        RECHARGE = Sequece("RECHARGE", [   NAV_DOCK_TASK
                                                                       CHARGE_ROBOT_TASK          ] )        

        TALK_MODE = Sequence( "TALK_MODE" ,   [  CheckDialogInitLeaf( ),
                                                                              DialogLeaf( )                       ] )
        
        LEARN_COURSE = Sequence ("LEARN_COURSE", [ CheckFollowModeLeaf(),
                                                                                       CheckCourseStatusLeaf(),     #already learned? what process is?
                                                                                       LearnCourseLeaf()       ] )
        
        OBJECT_RECOG = Sequence("OBJECT_RECOG", [ ObjRecognizeLeaf( ),
                                                                                       RecordLeaf( )                         ] )               # if nothing recognized?
                    
 #------------------------------  L2 branch
        STAY_BATT_HEALTHY = Sequence("STAY_BATT_HLTH",  [  CHECK_BATTERY,
                                                                                                   RECHARGE            ] )
        
        STAY_MCHN_HLTH=Sequence ("STAY_MCHN_HLTH", [ CheckMechnicLeaf( ),
                                                                                            HaveRestLeaf( )  ] )
        
        FACE_RECOG       = Sequence("FACE_RECOG",        [  FaceDetectLeaf( ),
                                                                                            FaceRecognizeLeaf( )      ] )

        CHATTER_MODE = Selector("CHATTER_MODE",    [ ChatterRandomLeaf( ),
                                                                                       ReportRandomLeaf( ),
                                                                                       TALK_MODE,
                                                                                        LEARN_COURSE               ] )

        SELF_LEARN        = Sequence("SELF_LEARN",      [  CheckEnergyLeaf( ),
                                                                                        OBJECT_RECOG               ] )


        FOLLOW_MODE = Sequence("FOLLOW_MODE",   [ CheckCpLeaf( ),
                                                                                      FollowCpLeaf( )                   ] )

        PLAY_ALONE = Sequence( "PLAY_ALONE", [  CheckEnergyLeaf( ),
                                                                              PlayRandom()                             ] )

        HAVE_REST = Sequence ( "HAVe_REST",   [ CheckEnergyLeaf( )
                                                                            HaveRestLeaf( )                               ] )


#------------------------------  L1 branch
        STAY_HEALTHY    = Selector("STAY_HEALTHY",     [ STAY_BATT_HEALTHY,
                                                                                        STAY_MCHN_HLTH            ] )
        
        SUDDEN_SEE        = Sequence("SUDDEN_SEE",       [ MotionDetectLeaf( ),
                                                                                           FACE_RECOG
                                                                                           #ObjRecognizeLeaf( )
                                                                                            ] )
        
        SUDDEN_HEAR     = Sequence("SUDDEN_HEAR",   [ SoundEvtDetectLeaf( ),
                                                                                         SoundAnalyzeLeaf( )        ] )
        
        BRAIN_STORM     = Selector("BRAIN_STORM",      [ CHATTER_MODE,
                                                                                        SELF_LEARN,
                                                                                        SHORE_ARROW                 ] )
        
        ROBOT_ACTIONS = Selector("ROBOT_ACTIONS", [  FOLLOW_MODE,
                                                                                        PLAY_ALONE,
                                                                                        HAVE_REST                         ] )               

        #+++  L1 add
        PARALLEL_ROOT.add_child(STAY_HEALTHY)
        PARALLEL_ROOT.add_child(SUDDEN_SEE)
        PARALLEL_ROOT.add_child(SUDDEN_HEAR)
        PARALLEL_ROOT.add_child(BRAIN_STORM)
        PARALLEL_ROOT.add_child(ROBOT_ACTIONS)

now I'm feeling easy to add/delete any node once needed with pi_trees now. It's clear and looks close to the tree we drew on paper.

regarding 2), I just see "Selector" and "RandomSelector" shares most of the code but inserting the random to self.children. So is there a way to write RandomSelector(also the one I want "WeightRandomSelector") with @Selector, then write "WeightRandomSelector" with @RandomSelector. Actually I don't understand the python @ well So I asked :-)

Thanks for your patient and help!

Nick Qian


在 2016年8月16日星期二 UTC+8上午10:21:02,Pi Robot写道:

Patrick Goebel

unread,
Aug 20, 2016, 9:42:21 AM8/20/16
to ros-by-...@googlegroups.com
Hi Nick,

Yes, one could probably refactor some of the code using decorators but for now I just added a weighted version of selector, sequence and iterator called WeightedRandomSelector, WeightedRandomSequence and WeightedRandomIterator.  You can see an example in the file pi_trees_lib/examples/weighted_random_example.py.

To get the update, run:


$ roscd pi_trees
$ git pull

This is for the indigo-devel branch.

Let me know if you run into any trouble.

--patrick

Nick Qian

unread,
Aug 21, 2016, 11:09:42 PM8/21/16
to ros-by-example
Hi Patrick,

This is really good! I need this in my project. 
Thanks!

Nick


在 2016年8月20日星期六 UTC+8下午9:42:21,Pi Robot写道:
Reply all
Reply to author
Forward
0 new messages