자식 노드를 실행하면서도 앞의 조건들이 여전히 유효한지 매 틱(tick)마다 처음부터 검토하여, 조건이 깨지면 진행 중이던 행동을 바로 중단시키는 반응형 순차 실행 노드
ㄴ 조건이 깨지면 Child1부터 시작
구조
| 구분 | Sequence | ReactiveSequence |
|---|---|---|
| 실행 방식 | 왼쪽 → 오른쪽 순차 실행, 한 번 실패하면 끝 | 루트부터 재평가, 실패/Running이면 이전 노드 다시 tick |
| 특징 | 한 번 tick하면 계속 진행, 조건 변화 무시 | 외부 조건 변화에 즉시 반응 |
| 장점 | 구조 단순, 직관적 | 환경 변화 즉시 반영, 로봇 행동에 유용 |
| 예제 상황 | 단순 작업 흐름 | 센서 상태 변화, 장애물 감지, 목표 변경 대응 |
1) 현재 실행 중인 ActionNode를 즉시 정지
ㄴ AsyncActionNode의 halt() 자동 실행
ㄴ RUNNING 중이던 행동이 중단됨
2) BT가 중단됨을 인식
ㄴ RUNNING → FAILURE 또는 HALTED 상태로 전환
ㄴ Control Node는 더 이상 이 노드를 유지하지 않음
3) 트리 흐름을 다시 재구성
ㄴ 현재 노드가 끝났으니 Control Node는 다음 행동을 선택
ㄴ BT는 루트에서 다시 tick
ㄴ 상황에 맞는 새로운 행동 실행
InterruptEvent = 외부 이벤트가 실행 중인 행동을 강제로 끊는 기능
AsyncActionNode에서만 의미가 있음 (오래 실행되기 때문)
halt() 호출로 즉시 중단 → BT는 새로운 흐름으로 재실행
반복적으로 장애물을 감지해야 하기에 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
<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 반환 | 오래 걸리는 작업 | 용도 |
|---|---|---|---|---|
| SyncActionNode | X | X | 불가 | 즉시 종료 행동 |
| AsyncActionNode | O | O | 가능 | 비동기/시간 필요한 행동 |
| StatefulActionNode | O | O | 가능 | 복잡한 단계적 액션 |
MoveForward노드에서 SUCCESS를 반환하면 BT가 끝나버리기 때문에, RUNNING을 반환해야 함.
ros2 launch neuronbot2_gazebo neuronbot2_world.launch.pycolcon build --symlink-install --packages-select bt_robotsource install/setup.bashros2 run bt_robot bt_main
ros2 topic pub -1 /interrupt_event std_msgs/String "data: 'end'"