1292.61 조건 노드의 부작용 금지 원칙
1. 부작용 금지 원칙의 정의
조건 노드의 부작용 금지 원칙(side-effect-free principle)이란, 조건 노드의 tick 함수가 환경의 상태, 블랙보드의 데이터, 외부 시스템의 상태를 변경하지 않아야 한다는 설계 원칙이다. 조건 노드는 순수하게 관찰(observation)과 판정(evaluation)만을 수행하며, 평가의 결과로 시스템의 상태가 변화하지 않는다. 이 원칙은 행동 트리에서 관찰과 행동의 분리(separation of observation and action)를 구현하는 핵심 제약이다 (Colledanchise & Ögren, Behavior Trees in Robotics and AI: An Introduction, 2018).
2. 부작용의 정의
부작용(side effect)이란 함수의 실행이 반환값의 산출 이외에 시스템의 관찰 가능한 상태를 변경하는 것을 의미한다. 조건 노드의 맥락에서 부작용에 해당하는 연산은 다음과 같다.
| 부작용 유형 | 설명 | 예시 |
|---|---|---|
| 블랙보드 쓰기 | 블랙보드 변수의 값 변경 | 변수 갱신, 플래그 설정 |
| 하드웨어 명령 | 액추에이터 또는 센서에 명령 송신 | 모터 구동, LED 제어 |
| 메시지 발행 | ROS2 토픽, 서비스 등의 메시지 송신 | 토픽 발행, 서비스 호출 |
| 파일 입출력 | 파일 시스템에 대한 쓰기 | 로그 파일 기록 |
| 전역 상태 변경 | 전역 변수 또는 공유 자원의 수정 | 카운터 증가, 플래그 토글 |
조건 노드에서 허용되는 연산은 읽기 전용(read-only) 연산에 한정된다. 블랙보드 변수 읽기, 센서 데이터 조회, 시스템 상태 확인 등의 관찰 연산은 부작용에 해당하지 않는다.
3. 부작용 금지의 근거
3.1 안전한 재평가 보장
반응형 제어 흐름 노드(ReactiveSequence, ReactiveFallback)는 매 tick마다 조건 노드를 재평가한다. 조건 노드에 부작용이 존재하면, 재평가 횟수에 따라 부작용이 반복적으로 발생하여 시스템의 상태가 의도하지 않게 변경된다.
ReactiveSequence
├─ Condition [C1] ← 매 tick마다 재평가
└─ Action [A1]
C1이 매 tick마다 재평가되므로, C1에 부작용이 있으면 해당 부작용이 tick 빈도(예: 초당 100회)만큼 반복 실행된다. 이는 조건 노드의 설계자가 의도한 동작이 아닐 가능성이 높다 (Faconti, BehaviorTree.CPP Documentation, 2024).
3.2 평가 횟수의 비결정성
제어 흐름 노드의 유형과 행동 트리의 구조에 따라 조건 노드가 평가되는 횟수는 가변적이다. 동일한 조건 노드가 한 tick에서 한 번 평가될 수도 있고, 여러 번 평가될 수도 있다. 부작용이 있는 조건 노드는 평가 횟수에 따라 시스템에 미치는 영향이 달라지므로, 행동 트리의 동작이 비결정적이 된다.
| 제어 흐름 노드 | 조건 재평가 빈도 | 부작용 영향 |
|---|---|---|
| Sequence (일반) | 한 번 | 부작용 1회 발생 |
| ReactiveSequence | 매 tick마다 | tick 빈도만큼 반복 |
| ReactiveFallback | 매 tick마다 | tick 빈도만큼 반복 |
| WhileDoElse | 매 tick마다 | tick 빈도만큼 반복 |
3.3 참조 투명성
부작용이 없는 조건 노드는 참조 투명성(referential transparency)을 가진다. 동일한 시스템 상태에서 조건 노드를 평가하면 항상 동일한 결과를 반환하며, 평가 자체가 시스템 상태를 변경하지 않으므로 평가의 반복이 결과에 영향을 미치지 않는다. 이 특성은 행동 트리의 정적 분석, 테스트, 검증을 용이하게 한다 (Colledanchise & Ögren, 2018).
4. 부작용 금지 위반의 사례
4.1 위반 사례 1: 블랙보드 쓰기
// 부작용 금지 위반
function BadCondition.tick():
distance = sensor.read_distance()
blackboard.set("last_distance", distance) // 부작용: 블랙보드 쓰기
if distance < threshold:
return Success
else:
return Failure
이 조건 노드는 거리 측정값을 블랙보드에 기록한다. ReactiveSequence의 자식으로 배치되면 매 tick마다 블랙보드가 갱신되어, 다른 노드가 참조하는 블랙보드 값이 조건 노드의 재평가에 의해 변경된다.
4.2 위반 사례 2: 카운터 증가
// 부작용 금지 위반
function BadCondition.tick():
evaluation_count += 1 // 부작용: 내부 상태 변경
if evaluation_count > max_evaluations:
return Failure
return Success
이 조건 노드는 평가 횟수를 추적한다. 제어 흐름 노드에 따라 평가 횟수가 달라지므로, 동일한 행동 트리에서도 구조에 따라 동작이 달라지는 비결정적 행동이 발생한다.
4.3 올바른 설계
// 부작용 금지 준수
function GoodCondition.tick():
distance = blackboard.get("distance") // 읽기 전용
if distance < threshold:
return Success
else:
return Failure
블랙보드에 대한 쓰기는 별도의 액션 노드에서 수행하고, 조건 노드는 블랙보드의 값을 읽기 전용으로만 접근한다 (Faconti, 2024).
5. 관찰과 행동의 분리
부작용 금지 원칙은 행동 트리에서 관찰(observation)과 행동(action)의 역할을 명확히 분리한다.
| 역할 | 노드 유형 | 허용 연산 | 부작용 |
|---|---|---|---|
| 관찰 | 조건 노드 | 읽기 전용 | 금지 |
| 행동 | 액션 노드 | 읽기/쓰기 | 허용 |
이 분리를 통해, 제어 흐름 노드는 조건 노드를 임의의 빈도로 안전하게 재평가할 수 있으며, 재평가가 시스템의 상태에 영향을 미치지 않음을 보장받는다. 행동 트리의 제어 흐름 의미론은 이 분리를 전제로 설계되었다 (Colledanchise & Ögren, 2018).
6. 로봇 공학에서의 의의
로봇 공학에서 조건 노드의 부작용 금지 원칙은 시스템의 안전성과 예측 가능성을 보장하는 핵심 설계 규율이다. 안전 조건 검사, 장애물 감지, 시스템 상태 감시 등의 조건 노드가 부작용 없이 동작함으로써, 이러한 조건의 반복적 재평가가 로봇의 물리적 행동이나 내부 상태에 의도하지 않은 변화를 유발하지 않는다. 이 원칙이 준수되면, 행동 트리의 설계자는 조건 노드의 배치 위치와 재평가 빈도를 시스템 안정성에 대한 우려 없이 자유롭게 결정할 수 있다 (Faconti, 2024).
참고 문헌
- Colledanchise, M. & Ögren, P. (2018). Behavior Trees in Robotics and AI: An Introduction. CRC Press.
- Faconti, D. (2024). BehaviorTree.CPP Documentation. https://www.behaviortree.dev/