중첩 조건의 구현 패턴 (Nested Condition Implementation Patterns)

중첩 조건의 구현 패턴 (Nested Condition Implementation Patterns)

1. 개요

중첩 조건(nested condition)은 AND, OR, NOT의 논리 연산을 다중 수준으로 결합하여 복잡한 의사 결정 로직을 표현하는 패턴이다. 행동 트리에서는 Sequence, Fallback, Inverter를 계층적으로 중첩하여 임의의 논리식을 구현할 수 있다. 본 절에서는 중첩 조건의 체계적 구성 방법, 실용적 패턴, 가독성 유지 전략을 다룬다.

2. 논리식의 행동 트리 변환

2.1 변환 규칙

임의의 명제 논리식(propositional logic formula)은 다음 규칙에 따라 행동 트리 구조로 변환된다.

논리식행동 트리 구조
A<Condition ID="A"/>
\neg A<Inverter><Condition ID="A"/></Inverter>
A \wedge B<Sequence><A/><B/></Sequence>
A \vee B<Fallback><A/><B/></Fallback>

이 규칙을 재귀적으로 적용하면, 임의의 중첩 깊이를 가진 논리식을 행동 트리로 변환할 수 있다.

2.2 예시: 복합 비행 안전 조건

비행 안전 조건을 다음 논리식으로 표현한다.

\text{Safe} = (\text{GPS} \wedge \text{Batt}) \wedge (\text{Wind} \vee \neg\text{Rain}) \wedge \neg\text{EStop}

이를 행동 트리로 변환하면 다음과 같다.

<Sequence name="FlightSafe">
    <Sequence name="CoreSystems">
        <Condition ID="IsGpsFixAvailable"/>
        <Condition ID="IsBatteryAbove"/>
    </Sequence>
    <Fallback name="WeatherAcceptable">
        <Condition ID="IsWindSpeedAcceptable"/>
        <Inverter>
            <Condition ID="IsRainDetected"/>
        </Inverter>
    </Fallback>
    <Inverter>
        <Condition ID="IsEmergencyStopActive"/>
    </Inverter>
</Sequence>

실용적 중첩 패턴

조건부 안전 등급

안전 등급에 따라 다른 수준의 조건을 적용하는 패턴이다.

<Fallback name="SafetyLevel">
    <!-- 등급 1: 완전 안전 -->
    <Sequence name="Level1_FullSafety">
        <Condition ID="AllSensorsOK"/>
        <Condition ID="BatteryFull"/>
        <Condition ID="WeatherClear"/>
        <Condition ID="CommsStrong"/>
    </Sequence>
    <!-- 등급 2: 부분 안전 -->
    <Sequence name="Level2_PartialSafety">
        <Condition ID="CriticalSensorsOK"/>
        <Condition ID="BatteryAdequate"/>
        <Fallback>
            <Condition ID="WeatherClear"/>
            <Condition ID="WeatherModerate"/>
        </Fallback>
    </Sequence>
    <!-- 등급 3: 최소 안전 -->
    <Sequence name="Level3_MinimalSafety">
        <Condition ID="CriticalSensorsOK"/>
        <Condition ID="BatteryMinimum"/>
    </Sequence>
</Fallback>

외부 Fallback은 가장 높은 안전 등급부터 시도하며, 해당 등급의 조건이 충족되지 않으면 다음 등급을 평가한다.

우선순위 조건 기반 행동 선택

중첩된 조건을 통해 상황에 따른 최적 행동을 선택한다.

<Fallback>
    <Sequence name="EmergencyCondition">
        <Fallback>
            <Condition ID="IsCollisionImminent"/>
            <Condition ID="IsBatteryCritical"/>
        </Fallback>
        <Action ID="EmergencyStop"/>
    </Sequence>
    <Sequence name="WarningCondition">
        <Sequence>
            <Inverter><Condition ID="IsPathValid"/></Inverter>
            <Condition ID="IsBatteryLow"/>
        </Sequence>
        <Action ID="ReturnToBase"/>
    </Sequence>
    <Action ID="ContinueMission"/>
</Fallback>

서브트리를 활용한 가독성 개선

중첩이 깊어지면 행동 트리의 가독성이 급격히 저하된다. 서브트리(SubTree)를 활용하여 중첩 조건을 명명된 단위로 캡슐화하면 가독성을 유지할 수 있다.

<!-- 메인 트리 -->
<BehaviorTree ID="MainMission">
    <ReactiveSequence>
        <SubTree ID="FlightSafetyCheck"/>
        <SubTree ID="MissionExecution"/>
    </ReactiveSequence>
</BehaviorTree>

<!-- 서브트리: 비행 안전 점검 -->
<BehaviorTree ID="FlightSafetyCheck">
    <Sequence>
        <SubTree ID="SensorReadyCheck"/>
        <SubTree ID="EnvironmentCheck"/>
        <Inverter>
            <Condition ID="IsEmergencyStopActive"/>
        </Inverter>
    </Sequence>
</BehaviorTree>

<!-- 서브트리: 센서 준비 점검 -->
<BehaviorTree ID="SensorReadyCheck">
    <Sequence>
        <Condition ID="IsGpsFixAvailable"/>
        <Condition ID="IsImuNormal"/>
        <Condition ID="IsLidarReceived"/>
    </Sequence>
</BehaviorTree>

<!-- 서브트리: 환경 점검 -->
<BehaviorTree ID="EnvironmentCheck">
    <Sequence>
        <Condition ID="IsWindSpeedAcceptable"/>
        <Condition ID="IsInsideGeofence"/>
        <Condition ID="IsAltitudeInRange"/>
    </Sequence>
</BehaviorTree>

설계 시 고려 사항

중첩 깊이의 제한

과도한 중첩은 행동 트리의 복잡도를 증가시키고, 디버깅과 유지보수를 어렵게 한다. 일반적으로 중첩 깊이는 3~4단계 이내로 제한하고, 그 이상이 필요한 경우 서브트리로 분리하는 것이 권장된다.

정규화(Normalization)

복잡한 중첩 조건은 논리적으로 동치인 더 단순한 형태로 변환할 수 있다. 예를 들어, 드모르간 법칙이나 분배법칙을 적용하여 중첩 깊이를 줄일 수 있다.

A \wedge (B \vee C) = (A \wedge B) \vee (A \wedge C)

다만, 트리의 구조적 단순성과 의미론적 명확성 사이의 균형을 고려하여야 한다.

2.3 평가 성능

중첩이 깊어지면 tick당 평가되는 노드의 수가 증가한다. 그러나 단락 평가에 의해 실제로 평가되는 노드의 수는 최악의 경우보다 적다. 성능이 중요한 경우, 자주 FAILURE(Sequence) 또는 SUCCESS(Fallback)를 반환하는 조건을 앞에 배치하여 불필요한 평가를 최소화한다.

3. 참고 문헌

  • Colledanchise, M., & Ogren, P. (2018). Behavior Trees in Robotics and AI: An Introduction. CRC Press.
  • BehaviorTree.CPP 공식 문서. https://www.behaviortree.dev/

버전날짜변경 사항
v0.12026-04-04초안 작성