1293.43 Memory와 Reactive 동작의 비교
1. 비교의 목적
행동 트리(Behavior Tree)에서 Memory(WithMemory)와 Reactive(WithoutMemory) 동작은 동일한 제어 노드 유형(Sequence, Fallback)에 대해 근본적으로 상이한 Tick 전파 정책을 정의한다. 두 동작 모드의 차이를 정확히 이해하는 것은 로봇 행동 설계에서 적절한 제어 노드를 선택하기 위한 필수적 전제이다. 본 절에서는 두 모드를 다각적 관점에서 체계적으로 비교한다(Colledanchise & Ogren, 2018).
2. Tick 전파 방식의 비교
2.1 Memory 모드
Memory 모드에서는 메모리 인덱스를 유지하여, 이전에 완료된 자식을 건너뛰고 RUNNING 중인 자식부터 Tick을 재개한다.
Tick N: 메모리 인덱스 = j
→ children[j].tick() // j 이전의 자식 건너뜀
2.2 Reactive 모드
Reactive 모드에서는 메모리 인덱스가 존재하지 않으며, 매 Tick마다 첫 번째 자식부터 모든 자식을 재평가한다.
Tick N:
→ children[0].tick() // 항상 0부터 시작
→ children[1].tick()
→ ...
3. Sequence에서의 비교
3.1 동일한 트리 구조에서의 동작 차이
트리 구조:
├── IsBatteryOk (조건)
├── IsPathClear (조건)
└── Navigate (비동기 액션)
3.1.1 Sequence (WithMemory)
| Tick | IsBatteryOk | IsPathClear | Navigate | Sequence |
|---|---|---|---|---|
| 1 | Tick→SUCCESS | Tick→SUCCESS | Tick→RUNNING | RUNNING |
| 2 | 건너뜀 | 건너뜀 | Tick→RUNNING | RUNNING |
| 3 | 건너뜀 | 건너뜀 | Tick→SUCCESS | SUCCESS |
Tick 2, 3에서 조건 노드가 재평가되지 않는다. 배터리가 부족해지거나 경로가 차단되어도 감지되지 않는다.
3.1.2 ReactiveSequence (WithoutMemory)
| Tick | IsBatteryOk | IsPathClear | Navigate | ReactiveSequence |
|---|---|---|---|---|
| 1 | Tick→SUCCESS | Tick→SUCCESS | Tick→RUNNING | RUNNING |
| 2 | Tick→SUCCESS | Tick→SUCCESS | Tick→RUNNING | RUNNING |
| 3 | Tick→SUCCESS | Tick→FAILURE | Halt | FAILURE |
Tick 3에서 IsPathClear의 조건 위반이 즉시 감지되어 Navigate가 중단된다.
4. Fallback에서의 비교
4.1 동일한 트리 구조에서의 동작 차이
트리 구조:
├── UsePrimaryNav (비동기 액션)
├── UseBackupNav (비동기 액션)
└── StopAndWait (비동기 액션)
4.1.1 Fallback (WithMemory)
| Tick | UsePrimaryNav | UseBackupNav | StopAndWait | Fallback |
|---|---|---|---|---|
| 1 | Tick→FAILURE | Tick→RUNNING | - | RUNNING |
| 2 | 건너뜀 | Tick→RUNNING | - | RUNNING |
| 3 | 건너뜀 | Tick→SUCCESS | - | SUCCESS |
Tick 2, 3에서 UsePrimaryNav가 재시도되지 않는다. 복구 가능 여부가 확인되지 않는다.
4.1.2 ReactiveFallback (WithoutMemory)
| Tick | UsePrimaryNav | UseBackupNav | StopAndWait | ReactiveFallback |
|---|---|---|---|---|
| 1 | Tick→FAILURE | Tick→RUNNING | - | RUNNING |
| 2 | Tick→FAILURE | Tick→RUNNING | - | RUNNING |
| 3 | Tick→SUCCESS | Halt | - | SUCCESS |
Tick 3에서 UsePrimaryNav가 복구되어 SUCCESS를 반환하면, UseBackupNav가 Halt되고 우선순위 복귀가 이루어진다.
5. 종합 비교표
| 비교 항목 | Memory 모드 | Reactive 모드 |
|---|---|---|
| Tick 시작 인덱스 | 메모리 인덱스 (가변) | 항상 0 (고정) |
| 이전 완료 자식 재평가 | 하지 않음 | 매 Tick마다 수행 |
| 환경 변화 감지 | 불가 | 즉시 가능 |
| 작업 진행 보존 | 보장 | 조건 변화 시 소실 |
| RUNNING 자식 Halt 빈도 | 낮음 | 높음 |
| Tick당 실행 비용 | T_{child_j} | \sum_{i=0}^{j} T_{child_i} |
| 의미론 (Sequence) | 단계적 작업 진행 | 조건 감시 + 작업 |
| 의미론 (Fallback) | 순차적 대안 시도 | 우선순위 기반 선택 |
| BehaviorTree.CPP 태그 | <Sequence>, <Fallback> | <ReactiveSequence>, <ReactiveFallback> |
6. 성능 관점의 비교
6.1 Tick당 노드 실행 수
RUNNING 자식의 인덱스를 j, 전체 자식 수를 N이라 하면:
\text{Memory: 실행 노드 수} = 1
\text{Reactive: 실행 노드 수} = j + 1
Memory 모드는 현재 활성 자식만 Tick하므로 실행 노드 수가 항상 1이다. Reactive 모드는 인덱스 0부터 j까지 j+1개의 노드를 Tick한다.
6.2 Halt 발생 빈도
Memory 모드에서 Halt가 발생하는 경우는 제어 노드 자체가 FAILURE(Sequence) 또는 SUCCESS(Fallback)를 반환하거나, 외부에서 Halt가 호출될 때뿐이다. Reactive 모드에서는 이전 자식의 반환 상태가 변경될 때마다 RUNNING 자식에 Halt가 발생한다. 환경이 동적으로 변화하는 경우 Reactive 모드에서의 Halt 빈도가 높아진다.
7. 안전성 관점의 비교
7.1 Memory 모드의 안전성 한계
Memory 모드에서 이전에 SUCCESS를 반환한 조건은 재평가되지 않으므로, 해당 조건이 이후에 위반되어도 감지되지 않는다. 이는 안전 관련 조건(비상 정지, 배터리 잔량, 운용 경계 등)이 지속적으로 충족되어야 하는 경우에 위험하다.
7.2 Reactive 모드의 안전성 보장
Reactive 모드는 매 Tick마다 모든 전제 조건을 재평가하므로, 조건 위반이 최대 1 Tick 지연 내에 감지된다. 이는 연속 감시(continuous monitoring)를 통한 런타임 안전성 보장을 제공한다.
8. 작업 완결성 관점의 비교
8.1 Memory 모드의 작업 완결성
Memory 모드에서 RUNNING 자식은 조건 변화에 의해 중단되지 않으므로, 작업이 완료될 때까지 지속적으로 실행된다. 이는 중간 중단이 허용되지 않는 원자적(atomic) 작업에 적합하다.
8.2 Reactive 모드의 작업 중단 가능성
Reactive 모드에서 조건이 위반되면 RUNNING 자식이 Halt되어 작업이 중단된다. 작업의 진행 상태가 소실되며, 조건이 복구되면 처음부터 재시작된다. 빈번한 조건 변동이 있는 환경에서는 작업이 반복적으로 중단되어 완료되지 못하는 상황이 발생할 수 있다.
9. 혼합 사용 패턴
실제 로봇 시스템에서는 Memory 모드와 Reactive 모드를 트리 내에서 혼합하여 사용하는 것이 일반적이다. 안전 감시가 필요한 상위 수준에서는 Reactive 모드를, 순차적 작업 수행이 필요한 하위 수준에서는 Memory 모드를 배치한다.
<ReactiveSequence>
<!-- Reactive: 안전 조건 지속 감시 -->
<IsEmergencyStopInactive/>
<IsBatteryAbove threshold="5"/>
<!-- Memory: 순차적 작업 수행 -->
<Sequence>
<MoveToPickup/>
<GraspObject/>
<MoveToDropoff/>
<ReleaseObject/>
</Sequence>
</ReactiveSequence>
이 구조에서 상위 ReactiveSequence는 안전 조건을 매 Tick마다 감시하고, 하위 Sequence는 조작 작업을 순차적으로 진행한다. 안전 조건이 위반되면 전체 작업이 즉시 중단되지만, 안전 조건이 유지되는 한 하위 Sequence는 이미 완료된 단계를 건너뛰고 현재 단계부터 재개한다.
10. 선택 기준 요약
| 판단 기준 | Memory 선택 | Reactive 선택 |
|---|---|---|
| 전제 조건의 지속적 유효성 검증 필요? | 아니오 | 예 |
| 이전 단계의 재실행이 무의미? | 예 | 아니오 |
| 작업 중단 시 진행 상태 보존 필요? | 예 | 아니오 |
| 우선순위 복귀가 필요? (Fallback) | 아니오 | 예 |
| 안전 관련 조건 포함? | 아니오 | 예 |
| Tick 실행 비용 최소화 필요? | 예 | 아니오 |
참고 문헌
- Colledanchise, M., & Ogren, P. (2018). Behavior Trees in Robotics and AI: An Introduction. CRC Press.
- Faconti, D. (2022). BehaviorTree.CPP documentation and API reference. https://www.behaviortree.dev/