## For instruction on writing tutorials ## http://www.ros.org/wiki/WritingTutorials #################################### ##FILL ME IN #################################### ## for a custom note with links: ## note = ## for the canned note of "This tutorial assumes that you have completed the previous tutorials:" just add the links ## note.0= ## descriptive title for the tutorial ## title = Create a Hierarchical State Machine ## multi-line description to be displayed in search ## description = This tutorial teaches you how to nest different state machines, creating a hierarchical state machine. ## the next tutorial description (optional) ## next = ## links to next tutorial (optional) ## next.0.link=[[smach/Tutorials/Calling Actions|Calling Actions from a SMACH State Machine]] ## next.1.link= ## what level user is this tutorial for ## level= BeginnerCategory ## keywords = #################################### <> <> == Creating some states == For this example, we create a number of states, each with a number of outcomes, input keys and output keys specified. {{{ #!python # State Foo class Foo(smach.State): def __init__(self, outcomes=['outcome1', 'outcome2']) def execute(self, userdata): return 'outcome1' # State Bar class Bar(smach.State): def __init__(self, outcomes=['outcome1']) def execute(self, userdata): return 'outcome4' # State Bas class Bas(smach.State): def __init__(self, outcomes=['outcome3']) def execute(self, userdata): return 'outcome3' }}} == Creating a hierarchical state machine == We create a top level state machine, and start adding states to it. One of the states we add is another state machine: {{{ #!python # Create the top level SMACH state machine sm_top = smach.StateMachine(outcomes=['outcome5']) # Open the container with sm_top: smach.StateMachine.add('BAS', Bas(), transitions={'outcome3':'SUB'}) # Create the sub SMACH state machine sm_sub = smach.StateMachine(outcomes=['outcome4']) # Open the container with sm_sub: # Add states to the container smach.StateMachine.add('FOO', Foo(), transitions={'outcome1':'BAR', 'outcome2':'outcome4'}) smach.StateMachine.add('BAR', Bar(), transitions={'outcome1':'FOO'}) smach.StateMachine.add('SUB', sm_sub, transitions={'outcome4':'outcome5'}) }}} The result looks like this. The only point to take away from this is that every state machine is also a normal state. So you can add a state machine to another state machine in the same way you add a state to a state machine. So dealing with userdata is not any different when you deal with hierarchical state machines: the sub state machine specifies input and output keys, and they get remapped when you add the sub state machine to the top level state machine. {{attachment:sm_expanded.png||width="750"}} == Example == This is a complete runnable example from the [[executive_smach_tutorials]] package. {{{#!wiki <> }}} Running the example: {{{ $ roscd smach_tutorials $ ./examples/state_machine_nesting2.py }}} The [[smach/Tutorials/Calling Actions|next tutorial]] teaches you how to call action servers from within a SMACH state machine. ## AUTOGENERATED DO NOT DELETE ## TutorialCategory ## FILL IN THE STACK TUTORIAL CATEGORY HERE ## LearningSMACHCategory