# Concurrence container

Description: This tutorial teaches you how to use the Concurrence container.

Tutorial Level: BEGINNER

Next Tutorial: Sequence container

```   1 from smach import Concurrence
```

## Specify concurrence outcomes

### Concurrence Outcome Map

The outcome map of a SMACH concurrence specifies the policy for determining the outcome of the concurrence based on the outcomes of its children. Specifically, the map is a dictionary where the keys are potential outcomes of the concurrence, and the values are dictionaries mapping child labels onto child outcomes. Once all the states in the concurrence have terminated, if one of these child-outcome mappings is satisfied, the concurrence will return its associated outcome. If none of the mappings are satisfied, the concurrence will return its default outcome.

```   1 cc = Concurrence(outcomes = ['outcome1', 'outcome2'],
2                  default_outcome = 'outcome1',
3                  input_keys = ['sm_input'],
4                  output_keys = ['sm_output'],
5                  outcome_map = {'succeeded':{'FOO':'succeeded',
6                                              'BAR':'outcome2'},
7                                 'outcome3':{'FOO':'outcome2'}})
8 with cc:
```

The example above specifies the following policy:

• When 'FOO' has outcome 'succeeded' and 'BAR' has outcome 'outcome2', the state machine will exit with outcome 'succeeded'.
• When 'FOO' has outcome 'outcome2', the state machine will exit with outcome 'outcome3', independent of the outcome of state BAR.

### Callbacks

If you want full control over a concurrence state machine, you can use the callbacks it provides, the child_termination_cb and the outcome_cb:

```   1 # gets called when ANY child state terminates
2 def child_term_cb(outcome_map):
3
4   # terminate all running states if FOO finished with outcome 'outcome3'
5   if outcome_map['FOO'] == 'outcome3':
6     return True
7
8   # terminate all running states if BAR finished
9   if outcome_map['BAR']:
10     return True
11
12   # in all other case, just keep running, don't terminate anything
13   return False
14
15
16 # gets called when ALL child states are terminated
17 def out_cb(outcome_map):
18    if outcome_map['FOO'] == 'succeeded':
19       return 'outcome1'
20    else:
21       return 'outcome2'
22
23
24 # creating the concurrence state machine
25 sm = Concurrence(outcomes=['outcome1', 'outcome2'],
26                  default_outcome='outcome1',
27                  input_keys=['sm_input'],
28                  output_keys=['sm_output'],
29                  child_termination_cb = child_term_cb,
30                  outcome_cb = out_cb)
31
32 with sm: