1295.78 XML에서의 ReactiveFallback 노드 정의

1. XML 기본 구문

BehaviorTree.CPP에서 ReactiveFallback 노드는 <ReactiveFallback> 태그로 정의한다.

<BehaviorTree ID="ReactiveFallbackBasic">
    <ReactiveFallback>
        <HighPriorityBranch />
        <MediumPriorityBranch />
        <LowPriorityBranch />
    </ReactiveFallback>
</BehaviorTree>

자식의 나열 순서가 우선순위를 결정하며, 앞에 위치한 자식이 높은 우선순위를 가진다. ReactiveFallback은 추가 속성(파라미터)을 필요로 하지 않는다.

2. 전형적 배치 패턴

2.1 조건-행동 쌍의 우선순위 배치

ReactiveFallback의 가장 전형적인 사용 패턴은, 각 우선순위 수준을 조건-행동 쌍의 Sequence로 구성하는 것이다.

<ReactiveFallback>
    <Sequence name="EmergencyResponse">
        <IsEmergency />
        <ExecuteEmergencyProtocol />
    </Sequence>
    <Sequence name="BatteryReturn">
        <IsBatteryLow threshold="15.0" />
        <ReturnToChargingStation />
    </Sequence>
    <Sequence name="ObstacleAvoidance">
        <IsObstacleNear distance="1.5" />
        <AvoidObstacle />
    </Sequence>
    <ExecuteMission waypoints="{mission_waypoints}" />
</ReactiveFallback>

각 Sequence의 첫 번째 자식이 조건 노드이다. 조건이 FAILURE이면 해당 Sequence가 FAILURE를 반환하고, ReactiveFallback이 다음 분기로 진행한다. 조건이 SUCCESS이면 해당 행동이 실행된다.

최하위의 ExecuteMission은 모든 상위 조건이 FAILURE일 때 실행되는 기본 행동이다.

2.2 다단계 비상 대응

<ReactiveFallback name="MultiLevelEmergency">
    <Sequence name="Level1_EStop">
        <IsEStopActive />
        <ImmediateStop />
    </Sequence>
    <Sequence name="Level2_Collision">
        <IsCollisionDetected />
        <StopAndRetract distance="0.3" />
    </Sequence>
    <Sequence name="Level3_SystemFault">
        <IsCriticalSystemFault />
        <SafeShutdownSequence />
    </Sequence>
    <NormalOperation />
</ReactiveFallback>

비상 상황의 심각도 순으로 분기를 배치한다. E-Stop이 최고 우선순위이다.

2.3 환경 적응 항법

<ReactiveFallback name="AdaptiveNavigation">
    <Sequence name="BadWeather">
        <IsSevereWeather wind_max="15.0" />
        <ShelterInPlace />
    </Sequence>
    <Sequence name="PoorVisibility">
        <IsVisibilityLow min_visibility="5.0" />
        <LidarOnlyNavigation />
    </Sequence>
    <Sequence name="WetSurface">
        <IsRaining />
        <CautiousNavigation speed_factor="0.5" />
    </Sequence>
    <NormalNavigation />
</ReactiveFallback>

기상 조건에 따라 항법 모드를 자동 전환한다.

3. 중첩 구조의 XML 표현

3.1 ReactiveFallback 내부에 ReactiveSequence

<ReactiveFallback>
    <Sequence name="Emergency">
        <IsEmergency />
        <EmergencyAction />
    </Sequence>
    <ReactiveSequence name="ConditionalMission">
        <IsLocalized />
        <IsPathValid />
        <NavigateToGoal goal="{target}" />
    </ReactiveSequence>
    <WaitForLocalization />
</ReactiveFallback>

비상 시 비상 행동이 선점된다. 비상이 아니면, 위치 추정과 경로가 유효한 동안 이동을 수행한다. 위치 추정이 실패하면 위치 복구를 시도한다.

3.2 ReactiveFallback 내부에 Parallel

<ReactiveFallback>
    <Sequence name="FireEmergency">
        <IsFireDetected />
        <ParallelAll max_failures="0">
            <ActivateSuppression />
            <SendFireAlert />
        </ParallelAll>
    </Sequence>
    <NormalPatrol />
</ReactiveFallback>

화재 감지 시 소화와 경보를 동시에 수행한다.

3.3 ReactiveFallback의 다층 중첩

<ReactiveSequence name="SafetyLayer">
    <IsHardwareSafe />
    <ReactiveFallback name="BehaviorSelection">
        <Sequence name="Emergency">
            <IsEmergency />
            <EmergencyStop />
        </Sequence>
        <ReactiveSequence name="Mission">
            <IsLocalized />
            <ReactiveFallback name="MissionMode">
                <Sequence>
                    <IsBatteryLow />
                    <ReturnToBase />
                </Sequence>
                <ExecuteMission />
            </ReactiveFallback>
        </ReactiveSequence>
        <SafeIdle />
    </ReactiveFallback>
</ReactiveSequence>

안전 보장 → 비상 대응 → 조건부 임무 → 배터리 관리의 다층 구조이다.

4. Nav2에서의 ReactiveFallback 사용

Nav2의 표준 행동 트리에서 ReactiveFallback이 사용되는 예시이다.

<!-- Nav2 navigate_to_pose_w_replanning_and_recovery.xml 발췌 -->
<ReactiveFallback name="NavigateRecoveryFallback">
    <GoalUpdated />
    <RoundRobin>
        <Sequence>
            <ComputePathToPose goal="{goal}" path="{path}" />
            <FollowPath path="{path}" />
        </Sequence>
        <SequenceStar>
            <ClearEntireCostmap name="ClearGlobalCostmap" 
                                service_name="global_costmap/clear" />
            <ClearEntireCostmap name="ClearLocalCostmap" 
                                service_name="local_costmap/clear" />
            <Spin spin_dist="1.57" />
            <Wait wait_duration="5" />
        </SequenceStar>
    </RoundRobin>
</ReactiveFallback>

GoalUpdatedSUCCESS를 반환하면(목표 갱신 시) 하위 항법/복구 행동이 모두 Halt되어, 새 목표에 대한 처리가 시작된다.

5. XML 정의의 모범 사례

  1. 분기별 명확한 네이밍: 각 Sequence 분기에 name 속성을 부여하여 우선순위 수준의 목적을 명시하라.

    <ReactiveFallback>
        <Sequence name="P0_EmergencyStop">...</Sequence>
        <Sequence name="P1_BatteryReturn">...</Sequence>
        <Sequence name="P2_NormalMission">...</Sequence>
    </ReactiveFallback>
    

2. **우선순위 순서의 주석**: 우선순위 순서와 근거를 XML 주석으로 기록하라.

    ```xml
    <ReactiveFallback>
        <!-- P0: 최고 우선순위 - E-Stop, 인간 안전 -->
        <Sequence name="P0_Safety">...</Sequence>
        <!-- P1: 시스템 보호 - 배터리, 온도 -->
        <Sequence name="P1_System">...</Sequence>
        <!-- P2: 임무 수행 - 기본 행동 -->
        <ExecuteMission />
    </ReactiveFallback>
  1. 기본 행동의 존재 보장: ReactiveFallback의 마지막 자식은 모든 상위 분기가 FAILURE일 때 실행되는 기본 행동이어야 한다. 기본 행동이 없으면 모든 조건이 비활성 시 ReactiveFallback이 FAILURE를 반환하여 로봇이 행동을 수행하지 않는 상태가 된다.

  2. 조건 노드의 경량 구현: ReactiveFallback의 각 분기 조건은 매 Tick에서 평가되므로, 조건 노드의 연산 비용을 최소화하라. 무거운 연산은 별도의 프로세스에서 수행하고, 조건 노드는 블랙보드 값만 읽도록 설계하라.