1292.19 Skipped 상태의 의미론적 정의

1. Skipped 상태의 기본 정의

행동 트리(Behavior Tree)에서 Skipped는 노드가 부모 노드의 제어 정책에 의해 의도적으로 실행이 건너뛰어졌음을 나타내는 반환 상태(Return Status)이다. Skipped는 Colledanchise와 Ogren(2018)의 고전적 행동 트리 형식 정의에서 제시된 세 가지 반환 상태(Success, Failure, Running)에는 포함되지 않으며, BehaviorTree.CPP 버전 4에서 도입된 확장 상태이다 (Faconti, BehaviorTree.CPP Documentation, 2024).

Skipped는 노드가 실행될 기회를 부여받지 못하였음을 의미하며, 해당 노드의 내부 로직이 전혀 실행되지 않았다는 점에서 Success, Failure, Running과 본질적으로 구분된다. 노드가 Skipped 상태를 반환하는 것은 노드 자체의 판단이 아니라, 부모 노드가 사전 조건(precondition) 평가를 통해 해당 자식의 실행이 불필요하다고 결정한 결과이다.

2. Skipped 도입의 배경

2.1 사전 조건 메커니즘과의 연관

BehaviorTree.CPP 버전 4에서는 노드에 사전 조건(precondition)과 사후 조건(postcondition)을 선언적으로 부착할 수 있는 메커니즘이 도입되었다. 사전 조건이 부착된 노드는 tick을 수신하기 전에 사전 조건이 먼저 평가되며, 사전 조건이 충족되지 않으면 노드의 실행이 건너뛰어진다. 이때 해당 노드는 Skipped 상태를 반환한다 (Faconti, 2024).

이 메커니즘이 도입되기 이전에는 조건 노드를 Sequence의 첫 번째 자식으로 배치하여 유사한 효과를 달성하였다. 그러나 이 방식은 트리 구조를 복잡하게 만들고, 조건 검사와 실행 노드 사이의 논리적 결합을 명시적으로 표현하기 어렵다는 한계가 있었다. 사전 조건과 Skipped 상태의 도입은 이러한 구조적 한계를 해결하기 위한 설계적 결정이다.

2.2 기존 상태 체계의 한계

Skipped가 도입되기 이전에는 사전 조건이 충족되지 않은 노드의 상태를 표현할 적절한 수단이 없었다. Failure를 사용하면 “노드가 실행되었으나 실패하였다“는 의미와 “노드가 실행조차 되지 않았다“는 의미를 구분할 수 없게 된다. 이 의미론적 모호성은 제어 흐름 노드의 동작에 예측하지 못한 부작용을 유발할 수 있다.

예를 들어, Sequence 노드의 자식이 사전 조건 미충족으로 Failure를 반환하면 Sequence 전체가 실패하게 되는데, 이는 해당 자식이 실행되지 않았을 뿐 실패한 것은 아니라는 의도와 부합하지 않는다. Skipped 상태는 이러한 의미론적 모호성을 해소한다.

3. Skipped의 의미론적 범주

3.1 비실행 상태로서의 Skipped

Skipped는 노드가 실행되지 않았음을 나타내는 비실행 상태(non-execution status)이다. Success, Failure, Running이 모두 노드의 실행 결과를 나타내는 반면, Skipped는 실행 자체가 발생하지 않았음을 나타낸다. 따라서 Skipped를 반환한 노드의 onStart, onRunning 콜백은 호출되지 않으며, 노드의 내부 상태에 어떠한 변경도 발생하지 않는다.

이 특성은 Skipped가 Idle과 공유하는 속성이다. 그러나 Idle이 노드가 tick을 수신하지 않은 상태를 나타내는 반면, Skipped는 tick이 도달하였으나 사전 조건에 의해 실행이 억제된 상태를 나타낸다는 점에서 구분된다.

3.2 종결 상태로서의 Skipped

Skipped는 종결 상태(terminal status)에 해당한다. 노드가 Skipped를 반환하면 해당 tick 주기 내에서 노드의 처리가 완료된 것으로 간주되며, 후속 tick에서의 계속적 실행을 요구하지 않는다. 이 점에서 Skipped는 Running과 구분되며, Success 및 Failure와 동일한 종결 범주에 속한다.

4. Skipped 상태의 발생 조건

4.1 사전 조건에 의한 Skipped

BehaviorTree.CPP에서 Skipped 상태가 발생하는 주된 메커니즘은 노드에 부착된 사전 조건의 평가이다. XML 기반 행동 트리 정의에서 노드에 _skipIf, _failureIf, _successIf, _while 등의 사전 조건 속성을 지정할 수 있으며, 이 조건이 특정 상태를 유발하도록 설정된 경우 노드의 실행이 건너뛰어진다.

_skipIf 속성이 참으로 평가되면 해당 노드는 Skipped를 반환한다. 이 평가는 노드의 tick 함수가 호출되기 전에 수행되므로, 노드의 내부 로직은 전혀 실행되지 않는다 (Faconti, 2024).

4.2 제어 흐름 노드의 조기 종료에 의한 Skipped

제어 흐름 노드의 조기 종료(short-circuit) 규칙에 의해서도 Skipped가 발생할 수 있다. Sequence 노드에서 자식이 Failure를 반환하면 후속 자식은 실행되지 않는데, BehaviorTree.CPP 버전 4에서는 이러한 미실행 자식의 상태를 Skipped로 명시적으로 표시할 수 있다. 이를 통해 트리의 실행 추적(execution trace)에서 어떤 노드가 실제로 실행되었고 어떤 노드가 건너뛰어졌는지를 명확히 구분할 수 있다.

5. 제어 흐름 노드에서 Skipped의 처리

5.1 Sequence 노드에서의 Skipped 처리

Sequence 노드의 자식이 Skipped를 반환하면, Sequence 노드는 해당 자식을 무시하고 다음 자식의 실행을 계속한다. 이는 Failure 반환 시 Sequence 전체가 실패하는 것과 대비되는 동작이다. Skipped된 자식은 “존재하지 않는 것처럼” 취급되어 Sequence의 성공/실패 판정에 영향을 미치지 않는다.

5.2 Fallback 노드에서의 Skipped 처리

Fallback 노드의 자식이 Skipped를 반환하면, Fallback 노드 역시 해당 자식을 무시하고 다음 자식의 실행을 계속한다. 이는 Success 반환 시 Fallback 전체가 성공하는 것과 대비된다. Skipped된 자식은 대안 탐색의 대상에서 제외된다.

5.3 모든 자식이 Skipped인 경우

제어 흐름 노드의 모든 자식이 Skipped를 반환하면 해당 제어 흐름 노드 자신도 Skipped를 반환한다. 이는 실행 가능한 자식이 하나도 존재하지 않았음을 상위 노드에 보고하는 것이며, Skipped의 상향 전파를 통해 트리의 상위 계층에서 적절한 대응을 결정할 수 있게 한다.

6. Skipped와 기존 상태의 비교

6.1 Skipped와 Failure의 차이

Skipped와 Failure는 모두 노드가 기대된 작업을 수행하지 않았음을 나타내지만, 그 의미론적 원인이 근본적으로 상이하다.

속성FailureSkipped
실행 여부실행되었으나 목표 미달성실행되지 않음
노드 내부 로직 호출호출됨호출되지 않음
자원 점유 가능성있음 (정리 필요)없음
Sequence에서의 효과즉시 실패 전파무시하고 계속 진행
Fallback에서의 효과다음 대안 시도무시하고 계속 진행

6.2 Skipped와 Idle의 차이

Skipped와 Idle은 모두 노드가 실행되지 않은 상태를 나타내지만, 그 발생 맥락이 상이하다. Idle은 tick이 해당 노드에 도달하지 않은 상태이며, Skipped는 tick이 도달하였으나 사전 조건에 의해 실행이 억제된 상태이다. Skipped는 의도적(intentional) 비실행인 반면, Idle은 구조적(structural) 비실행이라 할 수 있다.

7. Skipped의 설계적 함의

7.1 선언적 제어 흐름의 표현

Skipped 상태의 도입은 행동 트리의 제어 흐름을 더욱 선언적(declarative)으로 표현할 수 있게 한다. 사전 조건과 Skipped를 활용하면, 조건 검사를 위한 별도의 조건 노드를 트리 구조에 삽입하지 않고도 노드의 실행 조건을 직접 명시할 수 있다. 이는 트리의 구조적 복잡성을 감소시키고, 노드와 그 실행 조건 사이의 논리적 응집도(cohesion)를 향상시킨다.

7.2 실행 추적의 정밀화

Skipped 상태는 행동 트리의 실행 추적(execution trace)과 로깅(logging)에서 정보의 정밀도를 향상시킨다. Skipped가 없으면 노드의 미실행 이유가 “tick이 도달하지 않음“인지 “조건 미충족으로 건너뛰어짐“인지 구분할 수 없다. Skipped의 도입으로 행동 트리의 실행 이력을 보다 정확하게 재구성할 수 있으며, 이는 디버깅과 행동 분석에 유용하다.


참고 문헌

  • 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/