[ROS2] Behavior Tree (ReactiveSequence + InterruptEvent) + 실습

TaerinLog·2025년 12월 8일

Reactive Sequence

  • 자식 노드를 실행하면서도 앞의 조건들이 여전히 유효한지 매 틱(tick)마다 처음부터 검토하여, 조건이 깨지면 진행 중이던 행동을 바로 중단시키는 반응형 순차 실행 노드
    ㄴ 조건이 깨지면 Child1부터 시작

  • 구조

Sequence vs Reactive Sequence

구분SequenceReactiveSequence
실행 방식왼쪽 → 오른쪽 순차 실행, 한 번 실패하면 끝루트부터 재평가, 실패/Running이면 이전 노드 다시 tick
특징한 번 tick하면 계속 진행, 조건 변화 무시외부 조건 변화에 즉시 반응
장점구조 단순, 직관적환경 변화 즉시 반영, 로봇 행동에 유용
예제 상황단순 작업 흐름센서 상태 변화, 장애물 감지, 목표 변경 대응

InterruptEvent

  • 현재 실행 중인 행동(Action)을 강제로 중단시킬 수 있는 시스템 이벤트
    ㄴ BT 외부에서 어떤 상황이 발생했을 때 현재 돌고 있는 ActionNode를 즉시 중단시키고 BT의 흐름을 다시 조정하는 기능
    ㄴ 즉, Control Node와 Decorator가 아니라 BT 외부의 이벤트 시스템

InterruptEvent의 작업 순서

1) 현재 실행 중인 ActionNode를 즉시 정지
ㄴ AsyncActionNode의 halt() 자동 실행
ㄴ RUNNING 중이던 행동이 중단됨

2) BT가 중단됨을 인식
ㄴ RUNNING → FAILURE 또는 HALTED 상태로 전환
ㄴ Control Node는 더 이상 이 노드를 유지하지 않음

3) 트리 흐름을 다시 재구성
ㄴ 현재 노드가 끝났으니 Control Node는 다음 행동을 선택
ㄴ BT는 루트에서 다시 tick
ㄴ 상황에 맞는 새로운 행동 실행

요약

InterruptEvent = 외부 이벤트가 실행 중인 행동을 강제로 끊는 기능
AsyncActionNode에서만 의미가 있음 (오래 실행되기 때문)
halt() 호출로 즉시 중단 → BT는 새로운 흐름으로 재실행


(실습)

로봇 패턴 정의

  1. BT는 매 tick마다 ReactiveSequence를 재평가
  2. InterruptEvent가 들어오면 즉시 FAILURE 반환 → 전체 시퀀스 중단
  3. 장애물이 없으면
  • CheckObstacle = SUCCESS
  • Turn 생략
  • MoveForward 실행
  1. 장애물이 limit보다 가까우면
  • CheckObstacle = FAILURE
  • Fallback이 두 번째 자식(Turn) 실행
  • 회전 완료 전까지 RUNNING 유지
  1. 회전 완료 후 다시 ReactiveSequence 첫 노드부터 재평가
  2. 장애물이 없어지면 다시 MoveForward로 복귀

반복적으로 장애물을 감지해야 하기에 Reactive를 사용

패키지 생성

ros2 pkg create bt_robot --build-type ament_cmake --dependencies rclcpp std_msgs geometry_msgs sensor_msgs behaviortree_cpp_v3

파일 준비

  • 패키지 구조
bt_robot/
    ├── bt_xml/
    │     └── bt_nav.xml
    ├── launch/
    │     └── bt_launch.py
    └── src/
           ├── bt_main.cpp
           ├── bt_nodes.hpp
    ├── CMakeLists.txt
    ├── package.xml
  • bt_nav.xml
<root main_tree_to_execute="MainTree">
  <BehaviorTree ID="MainTree">
    <!-- 반복 -->
    <ReactiveSe!quence name="MainLoop">
    <InterruptEvent event="end" />
      <Fallback name="AvoidObstacle">
        <CheckObstacle distance="0.5"/>
        <Turn angle="2"/>
      </Fallback>
      <MoveForward speed="0.2"/>
    </ReactiveSequence>
  </BehaviorTree>
</root>

액션 노드

타입스레드RUNNING 반환오래 걸리는 작업용도
SyncActionNodeXX불가즉시 종료 행동
AsyncActionNodeOO가능비동기/시간 필요한 행동
StatefulActionNodeOO가능복잡한 단계적 액션

MoveForward노드에서 SUCCESS를 반환하면 BT가 끝나버리기 때문에, RUNNING을 반환해야 함.

시뮬레이션 환경 오픈

  • ros2 launch neuronbot2_gazebo neuronbot2_world.launch.py

패키지 빌드 및 BT 노드 실행

  • colcon build --symlink-install --packages-select bt_robot
  • source install/setup.bash
  • ros2 run bt_robot bt_main

인터럽트

  • ros2 topic pub -1 /interrupt_event std_msgs/String "data: 'end'"

profile
taerin

0개의 댓글