1294.55 Sequence 내부의 Fallback 중첩
1. 중첩 구조의 의미
Sequence 내부에 Fallback을 배치하는 중첩 구조는 “순차적 단계 중 특정 단계에서 여러 대안을 시도“하는 패턴을 구현한다. Sequence의 각 자식이 하나의 단계를 나타내고, 그 중 하나의 단계가 Fallback으로 구성되어 해당 단계의 달성을 위해 여러 방법을 순차적으로 시도한다(Colledanchise & Ogren, 2018).
2. 기본 구조
<Sequence>
<Action ID="Step1"/>
<Fallback>
<Action ID="Step2_MethodA"/>
<Action ID="Step2_MethodB"/>
<Action ID="Step2_MethodC"/>
</Fallback>
<Action ID="Step3"/>
</Sequence>
이 구조의 실행 흐름:
- Step1을 수행한다. 실패하면 Sequence 전체가 FAILURE를 반환한다.
- Step1이 성공하면, Step2를 위해 MethodA를 시도한다.
- MethodA가 실패하면 MethodB를, MethodB도 실패하면 MethodC를 시도한다.
- Fallback이 성공하면(어떤 방법으로든) Step3으로 진행한다.
- Fallback이 실패하면(모든 방법 실패) Sequence 전체가 FAILURE를 반환한다.
3. 논리적 해석
이 중첩 구조의 논리적 의미는:
\text{Step1} \land (\text{Step2\_A} \lor \text{Step2\_B} \lor \text{Step2\_C}) \land \text{Step3}
AND 연산(Sequence) 내부에 OR 연산(Fallback)이 포함된 복합 논리식이다.
실행 추적 예시
예시 1: 내부 Fallback의 첫 번째 대안 성공
Tick 1:
Sequence:
Step1 → SUCCESS
Fallback:
Step2_MethodA → SUCCESS ← 첫 대안 성공
Step3 → SUCCESS
→ SUCCESS
예시 2: 내부 Fallback의 두 번째 대안 성공
Tick 1:
Sequence:
Step1 → SUCCESS
Fallback:
Step2_MethodA → FAILURE
Step2_MethodB → SUCCESS ← 두 번째 대안 성공
Step3 → SUCCESS
→ SUCCESS
예시 3: 비동기 대안의 진행
Tick 1:
Sequence:
Step1 → SUCCESS
Fallback:
Step2_MethodA → FAILURE
Step2_MethodB → RUNNING ← 비동기 대안 진행 중
→ RUNNING
Tick 2 (SequenceWithMemory):
Sequence:
Fallback (재진입):
Step2_MethodB → SUCCESS
Step3 → SUCCESS
→ SUCCESS
예시 4: 내부 Fallback 전체 실패
Tick 1:
Sequence:
Step1 → SUCCESS
Fallback:
Step2_MethodA → FAILURE
Step2_MethodB → FAILURE
Step2_MethodC → FAILURE
→ FAILURE ← Fallback 전체 실패
Sequence → FAILURE ← 상위 Sequence도 실패
로봇 공학 적용 사례
사례 1: 물체 파지 임무
<Sequence>
<Action ID="IdentifyObject"/>
<Fallback>
<Action ID="TopGrasp"/>
<Action ID="SideGrasp"/>
<Action ID="PinchGrasp"/>
</Fallback>
<Action ID="LiftObject"/>
<Action ID="PlaceOnConveyor"/>
</Sequence>
물체를 인식한 후, 위쪽 파지를 먼저 시도하고 실패하면 측면 파지, 그래도 실패하면 핀치 파지를 시도한다. 어떤 방법으로든 파지에 성공하면 들어올리고 컨베이어에 배치한다.
사례 2: 다중 경로 네비게이션
<Sequence>
<Action ID="LocalizeSelf"/>
<Fallback>
<Action ID="NavigateGlobalPath"/>
<Action ID="NavigateLocalPath"/>
<Action ID="NavigateByWallFollowing"/>
</Fallback>
<Action ID="ReportArrival"/>
</Sequence>
자기 위치를 확인한 후, 글로벌 경로를 우선 시도하고, 실패하면 로컬 경로, 최후에는 벽 추종으로 이동한다.
사례 3: 통신 채널 선택이 포함된 임무
<Sequence>
<Action ID="CollectData"/>
<Fallback>
<Action ID="TransmitViaWifi"/>
<Action ID="TransmitViaCellular"/>
<Action ID="StoreLocally"/>
</Fallback>
<Action ID="ConfirmTransmission"/>
</Sequence>
다중 단계에서의 Fallback 중첩
여러 단계에 Fallback이 중첩되는 경우도 가능하다.
<Sequence>
<Fallback>
<Action ID="Step1_MethodA"/>
<Action ID="Step1_MethodB"/>
</Fallback>
<Fallback>
<Action ID="Step2_MethodA"/>
<Action ID="Step2_MethodB"/>
</Fallback>
<Action ID="Step3"/>
</Sequence>
이 구조의 논리적 의미는:
(\text{S1\_A} \lor \text{S1\_B}) \land (\text{S2\_A} \lor \text{S2\_B}) \land \text{S3}
각 단계에 대해 독립적으로 대안을 탐색하며, 모든 단계가 성공해야 전체가 성공한다.
4. 설계 시 고려사항
4.1 Sequence 변형의 선택
외부 Sequence가 SequenceWithMemory인 경우, Fallback이 성공한 후 다음 Tick에서 Fallback을 건너뛰고 다음 단계로 진행한다. ReactiveSequence인 경우, Fallback이 매 Tick마다 재평가되므로 주의가 필요하다.
4.2 Fallback 변형의 선택
내부 Fallback이 FallbackWithMemory인 경우, 실패한 대안을 건너뛴다. ReactiveFallback인 경우, 더 우선순위가 높은 대안이 가용해지면 전환한다. Sequence 내부의 Fallback은 일반적으로 FallbackWithMemory가 적합하다.
4.3 실패 전파
내부 Fallback의 모든 대안이 실패하면, Fallback이 FAILURE를 반환하고 이것이 외부 Sequence로 전파된다. 이 실패 전파가 의도된 동작인지 확인해야 하며, 필요시 Fallback의 마지막 자식에 항상 SUCCESS를 반환하는 안전 동작을 배치할 수 있다(Faconti, 2022).
참고 문헌
- 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/