1292.23 Tick의 정의와 역할
1. Tick의 형식적 정의
행동 트리(Behavior Tree)에서 Tick은 트리의 루트 노드(Root Node)에 전달되어 트리 전체의 단일 실행 순환(single execution cycle)을 유발하는 활성화 신호(activation signal)이다. Colledanchise와 Ogren(2018)은 tick을 다음과 같이 형식적으로 정의한다.
행동 트리 \mathcal{T} = \{f_0, r_0, \Delta_t\}에서 f_0은 루트 노드, r_0은 루트 노드의 반환 상태, \Delta_t는 tick 주기이다. \Delta_t 간격으로 루트 노드 f_0에 tick 신호가 전달되며, 이 신호를 수신한 f_0은 자신의 자식 노드에 tick을 재귀적으로 전달하여 트리 전체를 순회한다 (Colledanchise & Ogren, Behavior Trees in Robotics and AI, 2018).
각 노드 N의 관점에서 tick은 해당 노드의 실행 함수(execution function) f_N의 호출을 의미한다. f_N은 현재 환경 상태 E를 입력으로 받아 반환 상태 s \in \{Success, Failure, Running\}를 출력한다.
f_N : E \rightarrow \{Success, Failure, Running\}
Tick의 역할
실행 구동자로서의 역할
Tick의 가장 기본적인 역할은 행동 트리의 실행을 구동(drive)하는 것이다. 행동 트리의 노드는 자율적으로 실행을 개시하지 않으며, 반드시 tick의 수신을 통해서만 실행된다. tick이 없으면 행동 트리는 완전히 정지된 상태를 유지한다. 이 수동적(passive) 실행 모델은 행동 트리의 실행이 외부에서 통제 가능하며 예측 가능함을 보장한다.
행동 트리의 실행 엔진(execution engine)은 tick의 생성과 전달을 담당하는 유일한 주체이다. 실행 엔진이 tick을 생성하지 않으면 어떠한 노드도 실행되지 않으며, 실행 엔진이 tick의 빈도를 조절하면 행동 트리의 실행 속도가 그에 따라 조절된다.
상태 갱신 메커니즘으로서의 역할
Tick은 행동 트리가 환경의 현재 상태를 감지하고 이에 대응하는 상태 갱신 메커니즘(state update mechanism)이다. 각 tick에서 조건 노드(Condition Node)는 센서 데이터나 블랙보드(Blackboard)의 값을 평가하여 환경의 현재 상태를 판단하고, 제어 흐름 노드(Control Flow Node)는 이 판단에 기반하여 적절한 행동을 선택하며, 액션 노드(Action Node)는 선택된 행동을 실행한다.
이러한 주기적 상태 갱신은 로봇이 동적으로 변화하는 환경에서 적응적(adaptive) 행동을 수행할 수 있게 한다. 이전 tick에서 유효하였던 행동이 현재 tick에서는 더 이상 적절하지 않을 수 있으며, tick 메커니즘을 통해 이러한 변화가 감지되고 새로운 행동으로의 전환이 이루어진다.
비동기 작업 감시자로서의 역할
Tick은 비동기적으로 실행되는 장기 작업의 진행 상태를 주기적으로 감시(monitor)하는 역할을 수행한다. 비동기 액션 노드가 Running 상태에 있을 때, 매 tick마다 해당 노드의 onRunning 콜백이 호출되어 작업의 완료 여부가 검사된다. 이를 통해 행동 트리는 장기 실행 작업을 블로킹 없이 관리하면서도, 작업의 완료를 적시에 감지할 수 있다.
이 감시 역할은 타임아웃(timeout) 처리, 작업 중단(halt), 우선순위 변경 등의 제어 동작을 가능하게 한다. 비동기 작업이 Running 상태에서 지나치게 오래 머물면 Timeout 데코레이터가 이를 감지하여 작업을 중단시킬 수 있으며, 환경 변화에 의해 현재 작업보다 우선순위가 높은 작업이 발생하면 반응형 노드가 이를 감지하여 작업을 전환할 수 있다.
실행 흐름 제어자로서의 역할
Tick은 트리의 순회(traversal) 순서를 결정하고, 제어 흐름의 분기와 합류를 유발하는 역할을 수행한다. 제어 흐름 노드가 tick을 수신하면, 자신의 제어 정책(control policy)에 따라 어떤 자식에게 tick을 전달할지 결정한다. 이 결정은 이전 tick에서의 자식 반환 상태, 현재 자식의 상태(Idle 또는 Running), 그리고 노드 유형에 따른 규칙에 기반한다.
Sequence 노드는 왼쪽 자식부터 순차적으로 tick을 전달하며, Fallback 노드는 마찬가지로 왼쪽 자식부터 순차적으로 tick을 전달하되 자식의 반환 상태에 따른 조기 종료 규칙이 상이하다. Parallel 노드는 모든 자식에게 동시에 tick을 전달한다. 이러한 제어 정책의 다양성이 행동 트리의 표현력을 구성한다.
시간 이산화 수단으로서의 역할
Tick은 연속적인 물리 시간을 이산적(discrete)인 실행 단위로 분할하는 시간 이산화(time discretization) 수단이다. 로봇의 물리적 환경은 연속적으로 변화하지만, 행동 트리의 실행은 이산적인 tick 단위로 이루어진다. 이 이산화를 통해 행동 트리의 실행은 수학적으로 분석 가능한 이산 시간 시스템(discrete-time system)으로 모델링된다.
이산화의 정밀도는 tick 주기 \Delta_t에 의해 결정된다. \Delta_t가 작을수록 연속 시간 시스템에 대한 근사 정밀도가 향상되지만, 계산 부하가 증가한다. 이 관계는 디지털 제어 이론(digital control theory)에서의 샘플링 주기(sampling period)와 동일한 절충 구조를 갖는다 (Colledanchise & Ogren, 2018).
Tick과 노드의 상호작용
Tick 수신과 노드 실행
노드가 tick을 수신하면 다음과 같은 과정이 수행된다.
- 사전 조건 평가: 노드에 사전 조건(precondition)이 부착된 경우, 사전 조건이 먼저 평가된다. 미충족 시 노드는 Skipped를 반환하고 내부 로직은 실행되지 않는다.
- 콜백 호출: 노드의 현재 상태가 Idle이면 onStart 콜백이 호출되고, Running이면 onRunning 콜백이 호출된다.
- 반환 상태 결정: 콜백의 반환 값에 따라 노드의 새로운 상태가 결정된다.
- 상태 보고: 결정된 반환 상태가 부모 노드에게 전달된다.
Tick과 노드 유형의 관계
각 노드 유형은 tick을 상이하게 처리한다.
| 노드 유형 | Tick 수신 시 동작 |
|---|---|
| 루트 노드 | 자식에게 tick을 전달하고 반환 상태를 수신한다 |
| 제어 흐름 노드 | 제어 정책에 따라 선택적으로 자식에게 tick을 전달한다 |
| 데코레이터 노드 | 자식에게 tick을 전달하고 반환 상태를 변환한다 |
| 액션 노드 | 내부 작업 로직을 실행하고 반환 상태를 결정한다 |
| 조건 노드 | 조건 술어를 평가하고 Success 또는 Failure를 반환한다 |
Tick과 행동 트리의 전역 속성
Tick과 결정론성
Tick 메커니즘은 행동 트리의 결정론적(deterministic) 실행을 보장하는 기반이다. 동일한 환경 상태에서 동일한 tick을 수신하면, 행동 트리는 항상 동일한 실행 경로를 따르고 동일한 반환 상태를 산출한다. 이 결정론성은 tick이 동기적으로 실행되고, tick 실행 중에 외부 상태 변경이 발생하지 않는다는 전제하에 성립한다.
Tick과 모듈성
Tick은 행동 트리의 모듈성(modularity)을 지원한다. 각 노드는 tick을 수신하고 반환 상태를 보고하는 동일한 인터페이스를 따르므로, 노드의 내부 구현과 무관하게 트리의 어느 위치에나 배치할 수 있다. 이 균일한 tick 인터페이스가 행동 트리의 조합적(compositional) 설계를 가능하게 한다 (Colledanchise & Ogren, 2018).
참고 문헌
- Colledanchise, M. & Ogren, P. (2018). Behavior Trees in Robotics and AI: An Introduction. CRC Press.
- Faconti, D. (2024). BehaviorTree.CPP Documentation. https://www.behaviortree.dev/