1294.72 이동 로봇의 장애물 회피 Fallback

1294.72 이동 로봇의 장애물 회피 Fallback

1. 장애물 회피의 다중 전략적 특성

이동 로봇의 장애물 회피는 단일 전략으로 모든 상황을 처리할 수 없는 복합적 문제이다. 장애물의 유형(정적/동적), 크기, 형상, 위치에 따라 적합한 회피 전략이 달라지며, 하나의 전략이 실패하면 다른 전략을 시도해야 한다. Fallback 노드의 OR 의미론은 “하나라도 성공하면 충분한” 다중 장애물 회피 전략을 자연스럽게 표현한다(Colledanchise & Ogren, 2018).

2. 기본 장애물 회피 Fallback 구조

2.1 경로 재계획 기반 회피

<Fallback>
    <!-- 1순위: 경로가 유효하면 그대로 진행 -->
    <Sequence>
        <Condition ID="IsPathClear"/>
        <Action ID="FollowPath"/>
    </Sequence>
    <!-- 2순위: 장애물이 있으면 경로 재계획 -->
    <Sequence>
        <Action ID="ReplanPath"/>
        <Action ID="FollowPath"/>
    </Sequence>
    <!-- 3순위: 재계획 실패 시 정지 -->
    <Action ID="StopAndWait"/>
</Fallback>

경로가 깨끗하면 기존 경로를 따르고, 장애물이 발견되면 경로를 재계획하며, 재계획도 실패하면 정지하여 대기한다.

3. ROS2 Nav2의 장애물 회피 Fallback

3.1 Nav2의 복구 행동 구조

ROS2 Nav2 프레임워크는 네비게이션 실패 시 다단계 복구 행동을 Fallback으로 구성한다(Macenski et al., 2020).

<Fallback>
    <!-- 기본 네비게이션 시도 -->
    <SequenceWithMemory>
        <Action ID="ComputePathToPose" goal="{goal}" path="{path}"/>
        <Action ID="FollowPath" path="{path}"/>
    </SequenceWithMemory>
    <!-- 복구 행동 체인 -->
    <SequenceWithMemory>
        <Action ID="ClearEntireCostmap" service="global_costmap/clear"/>
        <Action ID="ClearEntireCostmap" service="local_costmap/clear"/>
        <Action ID="ComputePathToPose" goal="{goal}" path="{path}"/>
        <Action ID="FollowPath" path="{path}"/>
    </SequenceWithMemory>
    <SequenceWithMemory>
        <Action ID="Spin" spin_dist="1.57"/>
        <Action ID="ComputePathToPose" goal="{goal}" path="{path}"/>
        <Action ID="FollowPath" path="{path}"/>
    </SequenceWithMemory>
    <SequenceWithMemory>
        <Action ID="Wait" wait_duration="5"/>
        <Action ID="ComputePathToPose" goal="{goal}" path="{path}"/>
        <Action ID="FollowPath" path="{path}"/>
    </SequenceWithMemory>
    <SequenceWithMemory>
        <Action ID="BackUp" backup_dist="0.3" backup_speed="0.05"/>
        <Action ID="ComputePathToPose" goal="{goal}" path="{path}"/>
        <Action ID="FollowPath" path="{path}"/>
    </SequenceWithMemory>
</Fallback>

이 구조의 복구 전략은 다음과 같은 순서로 진행된다:

  1. 코스트맵 정리: 글로벌 및 로컬 코스트맵을 초기화하여 축적된 장애물 정보를 제거한 후 재시도한다. 센서 잡음에 의한 허위 장애물이 원인인 경우 이 단계에서 해결된다.
  2. 제자리 회전: 1.57라디안(약 90도) 회전하여 센서의 관측 범위를 변경한 후 재시도한다. 센서 사각지대에 의한 불완전한 환경 인식이 원인인 경우 효과적이다.
  3. 대기: 5초간 대기한 후 재시도한다. 동적 장애물(보행자 등)이 자연스럽게 이동하여 경로가 해소될 수 있다.
  4. 후진: 0.3미터 후진한 후 재시도한다. 좁은 공간에 갇힌 경우 빠져나올 수 있다.

3.2 Tick별 실행 흐름 분석

Tick 1:  ComputePathToPose→S, FollowPath→R (정상 네비게이션)
Tick 2:  FollowPath→R                      (이동 중)
Tick 3:  FollowPath→F                      (장애물 감지, 경로 추종 실패)
         → 1순위 Sequence FAILURE
         ClearCostmap(global)→R             (코스트맵 정리 시작)
Tick 4:  ClearCostmap(global)→S, ClearCostmap(local)→S,
         ComputePathToPose→S, FollowPath→R  (재계획 후 재시도)
Tick 5:  FollowPath→R                      (새 경로 추종 중)
Tick 6:  FollowPath→S                      → SUCCESS (장애물 회피 성공)

코스트맵 정리 후 재시도가 성공하면, 이후의 복구 전략(회전, 대기, 후진)은 시도되지 않는다.

4. 동적 장애물 회피 Fallback

4.1 ReactiveFallback을 이용한 동적 장애물 대응

<ReactiveFallback>
    <!-- 1순위: 경로가 깨끗하면 진행 -->
    <Sequence>
        <Condition ID="IsPathClear"/>
        <Action ID="FollowPath"/>
    </Sequence>
    <!-- 2순위: 장애물 감지 시 우회 -->
    <Sequence>
        <Condition ID="IsDetourPossible"/>
        <Action ID="FollowDetourPath"/>
    </Sequence>
    <!-- 3순위: 우회 불가 시 대기 -->
    <Action ID="StopAndWait"/>
</ReactiveFallback>

ReactiveFallback을 사용하면, 우회 경로를 추종하는 중에도 매 Tick 원래 경로가 깨끗해졌는지 재확인한다. 동적 장애물이 이동하여 원래 경로가 해소되면, 우회를 중단하고 원래 경로로 즉시 복귀한다.

Tick 1: IsPathClear→S, FollowPath→R         (정상 경로 추종)
Tick 2: IsPathClear→F, IsDetourPossible→S,
        FollowDetourPath→R                    (장애물 감지, 우회 시작)
Tick 3: IsPathClear→F, IsDetourPossible→S,
        FollowDetourPath→R                    (우회 진행 중)
Tick 4: IsPathClear→S, FollowPath→R          (원래 경로 복귀)
        FollowDetourPath→Halt                 (우회 중단)

5. 다중 센서 기반 장애물 회피

5.1 센서 우선순위에 따른 회피 전략

<Fallback>
    <!-- 라이다 기반 회피 (정밀) -->
    <Sequence>
        <Condition ID="IsLidarOperational"/>
        <Action ID="LidarBasedAvoidance"/>
    </Sequence>
    <!-- 카메라 기반 회피 (중간) -->
    <Sequence>
        <Condition ID="IsCameraOperational"/>
        <Action ID="VisionBasedAvoidance"/>
    </Sequence>
    <!-- 초음파 기반 회피 (기본) -->
    <Sequence>
        <Condition ID="IsUltrasonicOperational"/>
        <Action ID="UltrasonicBasedAvoidance"/>
    </Sequence>
    <!-- 모든 센서 불가 시 정지 -->
    <Action ID="EmergencyStop"/>
</Fallback>

라이다가 정상이면 가장 정밀한 라이다 기반 회피를 수행하고, 라이다 고장 시 카메라 기반으로, 카메라도 불가하면 초음파 기반으로 점진적으로 퇴화 운영한다.

6. 장애물 유형별 회피 전략

6.1 정적 장애물과 동적 장애물의 분류 대응

<Fallback>
    <!-- 경로 우 장애물 없음 -->
    <Sequence>
        <Condition ID="IsPathClear"/>
        <Action ID="FollowPath"/>
    </Sequence>
    <!-- 동적 장애물: 대기 후 재시도 -->
    <Sequence>
        <Condition ID="IsDynamicObstacle"/>
        <Fallback>
            <Sequence>
                <Action ID="Wait" duration="3000"/>
                <Condition ID="IsPathClear"/>
                <Action ID="FollowPath"/>
            </Sequence>
            <Action ID="ReplanAroundDynamic"/>
        </Fallback>
    </Sequence>
    <!-- 정적 장애물: 경로 재계획 -->
    <Sequence>
        <Condition ID="IsStaticObstacle"/>
        <Action ID="ReplanAroundStatic"/>
    </Sequence>
    <!-- 분류 불가: 안전 정지 -->
    <Action ID="SafeStop"/>
</Fallback>

동적 장애물의 경우 잠시 대기하면 장애물이 이동할 수 있으므로 먼저 대기를 시도하고, 대기 후에도 해소되지 않으면 우회 경로를 계획한다. 정적 장애물의 경우 대기가 무의미하므로 즉시 경로를 재계획한다.

7. 좁은 공간에서의 장애물 회피

7.1 협소 통로 통과 Fallback

<Fallback>
    <!-- 1순위: 정상 폭 통과 -->
    <Sequence>
        <Condition ID="IsPassageWideEnough"/>
        <Action ID="FollowPath"/>
    </Sequence>
    <!-- 2순위: 속도 감소 후 통과 -->
    <Sequence>
        <Condition ID="IsPassageNarrowButPassable"/>
        <Sequence>
            <Action ID="ReduceSpeed"/>
            <Action ID="FollowPathCarefully"/>
            <Action ID="RestoreSpeed"/>
        </Sequence>
    </Sequence>
    <!-- 3순위: 대안 경로 탐색 -->
    <Sequence>
        <Action ID="FindAlternativeRoute"/>
        <Action ID="FollowAlternativeRoute"/>
    </Sequence>
    <!-- 4순위: 통과 불가 보고 -->
    <Action ID="ReportPassageBlocked"/>
</Fallback>

8. 네비게이션 시퀀스 내 장애물 회피 통합

8.1 전체 네비게이션 트리에서의 위치

<ReactiveSequence>
    <!-- 안전 조건 감시 -->
    <Condition ID="IsBatteryOK"/>
    <Condition ID="IsLocalizationValid"/>
    <!-- 네비게이션 (장애물 회피 포함) -->
    <Fallback>
        <SequenceWithMemory>
            <Action ID="ComputePathToPose" goal="{goal}" path="{path}"/>
            <Action ID="FollowPath" path="{path}"/>
        </SequenceWithMemory>
        <SubTree ID="ObstacleRecoveryBehaviors"/>
    </Fallback>
</ReactiveSequence>

외부 ReactiveSequence가 안전 조건을 지속 감시하고, 내부 Fallback이 네비게이션 실패 시 장애물 복구 행동을 시도한다. 안전 조건과 장애물 회피가 계층적으로 분리되어 있다.

9. 설계 시 고려 사항

  1. 복구 전략의 순서: 비용이 낮고 빠른 전략(코스트맵 정리)을 앞에, 비용이 높고 느린 전략(후진, 대기)을 뒤에 배치한다.

  2. 동적 장애물 대응: 동적 장애물의 경우 ReactiveFallback을 사용하여, 장애물이 이동하면 즉시 원래 전략으로 복귀할 수 있도록 한다.

  3. 타임아웃 적용: 각 복구 전략에 타임아웃을 적용하여 단일 전략에서의 무한 대기를 방지한다. 특히 대기(Wait) 전략의 최대 대기 시간을 명시적으로 제한해야 한다.

  4. 최후 수단의 안전성: Fallback 체인의 마지막 전략은 반드시 안전한 행동(정지, 도움 요청 등)이어야 하며, 로봇이 장애물과 충돌하는 상황을 방지해야 한다.

  5. 코스트맵과의 연동: 장애물 회피 전략은 글로벌 및 로컬 코스트맵의 상태와 밀접하게 연관되므로, 코스트맵 정리 및 업데이트를 복구 전략에 포함해야 한다(Faconti, 2022).


참고 문헌

  • Colledanchise, M., & Ogren, P. (2018). Behavior Trees in Robotics and AI: An Introduction. CRC Press.
  • Faconti, D. (2022). BehaviorTree.CPP documentation and API reference. https://www.behaviortree.dev/
  • Macenski, S., Martín, F., White, R., & Clavero, J. G. (2020). The Marathon 2: A Navigation System. 2020 IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS), 2718–2725.