robotengine.state_machine

state_machine 是 robotengine 控制 owner 复杂状态的节点。

需要在 owner 中实现以下函数:

# 状态机每帧更新
def tick(self, state, delta):
    pass

# 状态机切换的条件
def get_next_state(self, state):
    pass

# 状态机切换时的回调
def transition_state(self, from, to):
    pass

实现良好的状态机需要注意防止产生状态切换的死循环

 1"""
 2
 3state_machine 是 robotengine 控制 owner 复杂状态的节点。
 4
 5需要在 owner 中实现以下函数:
 6
 7    # 状态机每帧更新
 8    def tick(self, state, delta):
 9        pass
10
11    # 状态机切换的条件
12    def get_next_state(self, state):
13        pass
14    
15    # 状态机切换时的回调
16    def transition_state(self, from, to):
17        pass
18    
19实现良好的状态机需要注意防止产生状态切换的死循环
20
21"""
22
23from robotengine.node import Node
24import time
25from robotengine.tools import error
26
27class StateMachine(Node):
28    """ 状态机节点 """
29    KEEP_CURRENT = -1
30    """ 维持当前状态的状态码 """
31
32    def __init__(self, initial_state, name="StateMachine"):
33        """ 
34        初始化状态机, 需要传递初始状态,通常是枚举类型 
35        
36            :param initial_state: 初始状态
37            :param name: 节点名称
38        """
39        super().__init__(name)
40        self.state_time = 0.0
41        """ 当前状态持续的时间 """
42        self.current_state = initial_state
43        """ 状态机的当前状态 """
44        self.first_tick = True
45        """ 是否是第一帧(刚初始化StateMachine时) """
46        self.freeze = False
47        """ 是否冻结状态机 """
48         
49    def _process(self, delta: float) -> None:
50        if self.freeze:
51            return
52        
53        start_transition_time = time.time()
54        while True:
55            if self.first_tick:
56                self.first_tick = False
57                self.owner.transition_state(None, self.current_state)
58
59            next = self.owner.get_next_state(self.current_state)
60            if next == StateMachine.KEEP_CURRENT:
61                break
62            self.owner.transition_state(self.current_state, next)
63            self.current_state = next
64            self.state_time = 0.0
65
66            if time.time() - start_transition_time > 1.0:
67                error(f"{self.owner.name} state_machine {self.current_state} transition timeout")
68
69        self.owner.tick(self.current_state, delta)
70        self.state_time += delta
71
72    def t_info(self, from_state, to_state) -> None:
73        self.rbprint(f"{from_state if from_state is not None else 'START'} -> {to_state} from:{self.name} ")
class StateMachine(robotengine.node.Node):
28class StateMachine(Node):
29    """ 状态机节点 """
30    KEEP_CURRENT = -1
31    """ 维持当前状态的状态码 """
32
33    def __init__(self, initial_state, name="StateMachine"):
34        """ 
35        初始化状态机, 需要传递初始状态,通常是枚举类型 
36        
37            :param initial_state: 初始状态
38            :param name: 节点名称
39        """
40        super().__init__(name)
41        self.state_time = 0.0
42        """ 当前状态持续的时间 """
43        self.current_state = initial_state
44        """ 状态机的当前状态 """
45        self.first_tick = True
46        """ 是否是第一帧(刚初始化StateMachine时) """
47        self.freeze = False
48        """ 是否冻结状态机 """
49         
50    def _process(self, delta: float) -> None:
51        if self.freeze:
52            return
53        
54        start_transition_time = time.time()
55        while True:
56            if self.first_tick:
57                self.first_tick = False
58                self.owner.transition_state(None, self.current_state)
59
60            next = self.owner.get_next_state(self.current_state)
61            if next == StateMachine.KEEP_CURRENT:
62                break
63            self.owner.transition_state(self.current_state, next)
64            self.current_state = next
65            self.state_time = 0.0
66
67            if time.time() - start_transition_time > 1.0:
68                error(f"{self.owner.name} state_machine {self.current_state} transition timeout")
69
70        self.owner.tick(self.current_state, delta)
71        self.state_time += delta
72
73    def t_info(self, from_state, to_state) -> None:
74        self.rbprint(f"{from_state if from_state is not None else 'START'} -> {to_state} from:{self.name} ")

状态机节点

StateMachine(initial_state, name='StateMachine')
33    def __init__(self, initial_state, name="StateMachine"):
34        """ 
35        初始化状态机, 需要传递初始状态,通常是枚举类型 
36        
37            :param initial_state: 初始状态
38            :param name: 节点名称
39        """
40        super().__init__(name)
41        self.state_time = 0.0
42        """ 当前状态持续的时间 """
43        self.current_state = initial_state
44        """ 状态机的当前状态 """
45        self.first_tick = True
46        """ 是否是第一帧(刚初始化StateMachine时) """
47        self.freeze = False
48        """ 是否冻结状态机 """

初始化状态机, 需要传递初始状态,通常是枚举类型

:param initial_state: 初始状态
:param name: 节点名称
KEEP_CURRENT = -1

维持当前状态的状态码

state_time

当前状态持续的时间

current_state

状态机的当前状态

first_tick

是否是第一帧(刚初始化StateMachine时)

freeze

是否冻结状态机

def t_info(self, from_state, to_state) -> None:
73    def t_info(self, from_state, to_state) -> None:
74        self.rbprint(f"{from_state if from_state is not None else 'START'} -> {to_state} from:{self.name} ")