1292.13 데코레이터 노드 (Decorator Node)의 개요

1. 서론

데코레이터 노드(Decorator Node)는 행동 트리(Behavior Tree)에서 정확히 하나의 자식 노드를 보유하며, 해당 자식 노드의 반환 상태를 변환하거나 자식 노드의 실행 흐름을 제어하는 단항(Unary) 노드이다. 데코레이터 노드는 제어 흐름 노드(Control Flow Node)처럼 자식을 갖는 내부 노드이면서도, 다수의 자식이 아닌 단일 자식만을 관리한다는 점에서 구별된다. 본 절에서는 데코레이터 노드의 정의, 구조적 특성, 동작 원리, 그리고 주요 유형을 형식적으로 기술한다.

2. 데코레이터 노드의 정의

데코레이터 노드 D는 정확히 하나의 자식 노드 c를 보유하는 노드로, Tick을 수신하면 자식 노드에 Tick을 전파하고, 자식 노드의 반환 상태를 자체적인 변환 정책(Transformation Policy)에 따라 변환하여 상위 노드에 반환한다. 형식적으로 다음과 같이 정의된다:

D : (\text{Tick}, c) \rightarrow f(\text{status}(c))

여기서 f는 데코레이터 노드의 변환 함수(Transformation Function)이며, 자식 노드의 반환 상태를 입력으로 받아 새로운 반환 상태를 출력한다:

f : \{\text{Success}, \text{Failure}, \text{Running}\} \rightarrow \{\text{Success}, \text{Failure}, \text{Running}\}

2.1 단일 자식 제약

데코레이터 노드의 자식 노드 수는 정확히 1이다:

|\text{children}(D)| = 1

이 제약은 데코레이터 노드를 다수의 자식을 관리하는 제어 흐름 노드(Sequence, Fallback, Parallel 등)와 구조적으로 구별한다. 데코레이터 노드의 자식은 실행 노드, 제어 흐름 노드, 또는 다른 데코레이터 노드 중 어느 것이든 될 수 있다.

3. 데코레이터 노드의 구조적 위치

행동 트리의 계층 구조에서 데코레이터 노드는 내부 노드(Internal Node)에 위치한다. 리프 노드(실행 노드)도 아니고, 다수의 자식을 관리하는 제어 흐름 노드도 아닌, 단일 자식에 대한 래퍼(Wrapper) 역할을 수행하는 중간 계층이다.

        [Root]
          |
      [Sequence]
       /       \
  [Inverter]   [Action: Move]
      |
  [Condition: IsObstacle]

위 구조에서 Inverter는 데코레이터 노드로서, Condition: IsObstacle 노드의 반환 상태를 반전시킨다. 장애물이 탐지되지 않았을 때(Failure) Success를 반환함으로써, “장애물이 없다“라는 의미론적 조건으로 변환한다.

4. 데코레이터 노드의 동작 원리

4.1 Tick 전파와 상태 변환

데코레이터 노드의 동작은 다음의 순서로 수행된다:

  1. Tick 수신: 상위 노드(부모 노드)로부터 Tick을 수신한다.
  2. 자식 노드에 Tick 전파: 자체적인 전달 정책에 따라 자식 노드에 Tick을 전파한다. 일부 데코레이터 노드는 조건에 따라 Tick 전파를 보류할 수 있다.
  3. 자식 반환 상태 수신: 자식 노드가 반환한 상태를 수신한다.
  4. 변환 함수 적용: 변환 함수 f를 적용하여 자식의 반환 상태를 변환한다.
  5. 변환된 상태 반환: 변환된 반환 상태를 상위 노드에 반환한다.

4.2 변환 함수의 유형

데코레이터 노드의 변환 함수는 다음과 같은 유형으로 분류된다:

변환 유형설명
상태 반전(Inversion)자식의 Success를 Failure로, Failure를 Success로 변환한다.
상태 강제(Forcing)자식의 반환 상태와 무관하게 특정 상태를 강제로 반환한다.
반복 제어(Repetition Control)자식 노드의 실행을 지정된 횟수만큼 반복한다.
재시도 제어(Retry Control)자식 노드가 실패할 경우 지정된 횟수만큼 재실행한다.
시간 제어(Temporal Control)자식 노드의 실행에 시간 제한을 부과하거나 지연을 삽입한다.
실행 횟수 제어(Execution Count Control)자식 노드가 최초 1회만 실행되도록 제한한다.

5. 주요 데코레이터 노드의 개요

5.1 Inverter (반전 데코레이터)

Inverter는 자식 노드의 Success를 Failure로, Failure를 Success로 변환한다. Running 상태는 변환 없이 그대로 전달된다.

f_{\text{Inverter}}(s) = \begin{cases} \text{Failure} & \text{if } s = \text{Success} \\ \text{Success} & \text{if } s = \text{Failure} \\ \text{Running} & \text{if } s = \text{Running} \end{cases}

논리적으로 NOT 연산자에 대응하며, 조건 노드의 의미를 반전시키는 데 빈번하게 사용된다.

5.2 ForceSuccess (강제 성공 데코레이터)

ForceSuccess는 자식 노드의 반환 상태가 Failure이더라도 이를 Success로 변환하여 반환한다. Running 상태는 그대로 전달된다.

f_{\text{ForceSuccess}}(s) = \begin{cases} \text{Success} & \text{if } s \in \{\text{Success}, \text{Failure}\} \\ \text{Running} & \text{if } s = \text{Running} \end{cases}

5.3 ForceFailure (강제 실패 데코레이터)

ForceFailure는 자식 노드의 반환 상태가 Success이더라도 이를 Failure로 변환하여 반환한다.

f_{\text{ForceFailure}}(s) = \begin{cases} \text{Failure} & \text{if } s \in \{\text{Success}, \text{Failure}\} \\ \text{Running} & \text{if } s = \text{Running} \end{cases}

5.4 Repeat (반복 데코레이터)

Repeat는 자식 노드를 지정된 횟수 N만큼 반복 실행한다. 자식 노드가 Success를 반환할 때마다 반복 카운터를 증가시키며, N회 모두 Success이면 최종적으로 Success를 반환한다. 자식 노드가 중간에 Failure를 반환하면, Repeat 노드 역시 Failure를 반환한다.

5.5 Retry (재시도 데코레이터)

Retry는 자식 노드가 Failure를 반환하였을 때, 지정된 최대 재시도 횟수 N까지 자식 노드를 재실행한다. 자식 노드가 Success를 반환하면 Retry 노드도 Success를 반환하고, N회 모두 Failure이면 최종적으로 Failure를 반환한다.

5.6 Timeout (시간 제한 데코레이터)

Timeout은 자식 노드의 실행에 시간 제한 T를 부과한다. 자식 노드가 T 시간 이내에 Success 또는 Failure를 반환하지 않으면, Timeout 데코레이터가 자식 노드에 Halt를 전파하고 Failure를 반환한다.

5.7 Delay (지연 데코레이터)

Delay는 자식 노드에 Tick을 전파하기 전에 지정된 시간 T만큼 대기한다. 대기 기간 동안 Running 상태를 반환하며, 대기가 완료된 이후에 자식 노드에 Tick을 전파한다.

5.8 RunOnce (단회 실행 데코레이터)

RunOnce는 자식 노드가 최초 1회만 실행되도록 제한한다. 첫 번째 실행에서 자식 노드가 반환한 상태를 기록하고, 이후의 Tick에서는 자식 노드를 재실행하지 않고 기록된 상태를 직접 반환한다.

5.9 KeepRunningUntilFailure (실패까지 지속 실행 데코레이터)

KeepRunningUntilFailure는 자식 노드가 Success를 반환하면 이를 Running으로 변환하여 자식 노드의 실행을 지속시킨다. 자식 노드가 Failure를 반환하면 비로소 Failure를 상위에 전달한다.

f_{\text{KRUF}}(s) = \begin{cases} \text{Running} & \text{if } s = \text{Success} \\ \text{Running} & \text{if } s = \text{Running} \\ \text{Failure} & \text{if } s = \text{Failure} \end{cases}

6. 데코레이터 노드와 설계 패턴의 관계

데코레이터 노드의 명칭은 객체 지향 설계 패턴의 데코레이터 패턴(Decorator Pattern)에서 유래하였다. 데코레이터 패턴은 기존 객체의 기능을 변경하지 않으면서 새로운 기능을 동적으로 추가하는 구조적 설계 패턴이다. 행동 트리의 데코레이터 노드 역시 자식 노드의 내부 구현을 변경하지 않으면서, 자식 노드의 반환 상태나 실행 흐름에 대한 추가적인 제어를 부여한다.

이러한 설계는 행동 트리의 모듈성(Modularity)을 향상시킨다. 기존 액션 노드나 조건 노드의 코드를 수정하지 않고, 데코레이터 노드를 삽입하는 것만으로 반전, 반복, 시간 제한 등의 행동 변형을 적용할 수 있다.

7. 데코레이터 노드의 Halt 전파

데코레이터 노드가 상위 노드로부터 Halt를 수신하면, 자식 노드가 Running 상태에 있는 경우 자식 노드에 Halt를 전파하여야 한다. 이는 제어 흐름 노드의 Halt 전파 규칙과 동일하다:

\text{halt}(D) \implies \text{status}(c) = \text{Running} \implies \text{halt}(c)

특히 Timeout, Repeat, Retry 등 내부 상태를 유지하는 데코레이터 노드에서는, Halt 수신 시 내부 카운터, 타이머 등의 상태 변수도 함께 초기화되어야 한다.

8. 데코레이터 노드의 설계 원칙

데코레이터 노드를 설계하고 활용할 때 다음의 원칙을 준수하여야 한다:

  1. 단일 변환 원칙(Single Transformation Principle): 하나의 데코레이터 노드는 하나의 명확한 변환 또는 제어만을 수행하여야 한다. 복합적인 변환이 필요한 경우, 데코레이터 노드를 중첩하여 적용한다.
  2. 투명성 보장(Transparency Guarantee): 데코레이터 노드는 자식 노드의 내부 구현에 의존하지 않아야 한다. 어떤 유형의 자식 노드에도 적용할 수 있는 범용성을 유지하여야 한다.
  3. Halt 안전성: 데코레이터 노드가 Halt를 수신하면, 자식 노드의 Halt 전파와 자체 내부 상태의 초기화가 완전히 수행되어야 한다.
  4. Running 투과성: 대부분의 데코레이터 노드에서 자식 노드의 Running 상태는 변환 없이 그대로 상위에 전달된다. Running 상태의 의미를 임의로 변경하면 행동 트리의 실행 의미론이 훼손될 수 있다.

9. 데코레이터 노드의 로봇 공학적 의의

데코레이터 노드는 행동 트리의 유연성과 표현력을 현저히 확장하는 구성 요소이다. 기본적인 액션 노드와 조건 노드만으로는 구현이 곤란한 행동 변형—반전, 반복, 재시도, 시간 제한 등—을 트리 구조의 조작만으로 실현할 수 있다.

로봇 공학에서 데코레이터 노드의 전형적인 활용 사례는 다음과 같다:

활용 사례데코레이터역할
장애물 부재 확인Inverter장애물 탐지 조건의 부정
복구 행동 재시도Retry복구 액션 실패 시 N회 재시도
순찰 반복Repeat순찰 경로 순회를 N회 반복
응답 시간 제한Timeout외부 서비스 응답 대기에 시간 상한 부과
초기화 1회 실행RunOnce센서 캘리브레이션을 최초 1회만 수행
작업 실패까지 지속KeepRunningUntilFailure감시 작업의 지속적 실행

이러한 데코레이터 노드의 조합적 활용은 로봇의 행동 제어에 높은 수준의 적응성과 견고성을 부여한다.


참고 문헌

  • Colledanchise, M., & Ögren, P. (2018). Behavior Trees in Robotics and AI: An Introduction. CRC Press.
  • Gamma, E., Helm, R., Johnson, R., & Vlissides, J. (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley.
  • Marzinotto, A., Colledanchise, M., Smith, C., & Ögren, P. (2014). “Towards a Unified Behavior Trees Framework for Robot Control.” Proceedings of the IEEE International Conference on Robotics and Automation (ICRA), 5420–5427.
  • Faconti, D., & Contributors. (2024). BehaviorTree.CPP Documentation. https://www.behaviortree.dev/

v1.0