-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbt_common.py
121 lines (103 loc) · 4.57 KB
/
bt_common.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# vim:fenc=utf-8
# Ozer Ozkahraman ([email protected])
# common definitions and global variables
import py_trees as pt
###############################################################
# GENERIC TREE NODES AND SUCH
###############################################################
class Sequence(pt.composites.Selector):
"""
Reactive sequence overidding sequence with memory, py_trees' only available sequence.
"""
def __init__(self, name="Sequence", children=None):
super(Sequence, self).__init__(name=name, children=children)
def tick(self):
"""
Run the tick behaviour for this selector. Note that the status
of the tick is always determined by its children, not
by the user customised update function.
Yields:
:class:`~py_trees.behaviour.Behaviour`: a reference to itself or one of its children
"""
self.logger.debug("%s.tick()" % self.__class__.__name__)
# Required behaviour for *all* behaviours and composites is
# for tick() to check if it isn't running and initialise
if self.status != pt.common.Status.RUNNING:
# selectors dont do anything specific on initialisation
# - the current child is managed by the update, never needs to be 'initialised'
# run subclass (user) handles
self.initialise()
# run any work designated by a customised instance of this class
self.update()
previous = self.current_child
for child in self.children:
for node in child.tick():
yield node
if node is child:
if node.status == pt.common.Status.RUNNING or node.status == pt.common.Status.FAILURE:
self.current_child = child
self.status = node.status
if previous is None or previous != self.current_child:
# we interrupted, invalidate everything at a lower priority
passed = False
for child in self.children:
if passed:
if child.status != pt.common.Status.INVALID:
child.stop(pt.common.Status.INVALID)
passed = True if child == self.current_child else passed
yield self
return
# all children succeded, set succed ourselves and current child to the last bugger who failed us
self.status = pt.common.Status.SUCCESS
try:
self.current_child = self.children[-1]
except IndexError:
self.current_child = None
yield self
class SetBlackboardVariable(pt.behaviours.Running):
"""
Set the specified variable on the blackboard.
Usually we set variables from inside other behaviours, but can
be convenient to set them from a behaviour of their own sometimes so you
don't get blackboard logic mixed up with more atomic behaviours.
Args:
name (:obj:`str`): name of the behaviour
variable_name (:obj:`str`): name of the variable to set
variable_value (:obj:`any`): value of the variable to set
.. todo:: overwrite option, leading to possible failure/success logic.
"""
def __init__(self,
name="Set Blackboard Variable",
variable_name="dummy",
variable_value=None
):
"""
:param name: name of the behaviour
:param variable_name: name of the variable to set
:param value_name: value of the variable to set
"""
super(SetBlackboardVariable, self).__init__(name)
self.variable_name = variable_name
self.variable_value = variable_value
def initialise(self):
self.blackboard = pt.blackboard.Blackboard()
self.blackboard.set(self.variable_name, self.variable_value, overwrite=True)
class Counter(pt.behaviour.Behaviour):
# A simple counter
def __init__(self, n, name='Counter', reset=False):
# count
self.i = 0
self.n = n
# resetting
self.reset = reset
# become a behaviour
super(Counter, self).__init__(name)
def update(self):
# increment the count
self.i += 1
# react to the result
return pt.common.Status.FAILURE if self.i <= self.n else pt.common.Status.SUCCESS
def terminate(self, status):
self.i = 0 if status == pt.common.Status.SUCCESS and self.reset else self.i