1293.16 적응적 Tick 주기의 설계
1. 적응적 Tick 주기의 개념
적응적 Tick 주기(adaptive tick rate)란 행동 트리(Behavior Tree)의 Tick 주파수를 고정된 값으로 유지하지 않고, 시스템의 상태, 환경 조건, 또는 계산 부하에 따라 동적으로 조정하는 설계 방법이다. 고정 Tick 주기가 모든 상황에서 동일한 빈도로 트리를 평가하는 것에 비해, 적응적 Tick 주기는 높은 응답성이 필요한 상황에서는 Tick 주파수를 증가시키고, 환경이 안정적인 상황에서는 Tick 주파수를 감소시킴으로써 응답성과 계산 효율성 간의 트레이드오프를 동적으로 최적화한다(Colledanchise & Ogren, 2018).
2. 적응적 Tick 주기의 동기
고정 Tick 주기는 설계가 단순하고 시간적 예측 가능성이 높은 반면, 모든 상황에 최적인 단일 Tick 주파수를 선정하기 어렵다는 구조적 한계를 가진다. 안전을 위해 최악의 경우를 기준으로 높은 Tick 주파수를 설정하면 대부분의 시간에서 불필요한 계산이 수행되고, 자원 절약을 위해 낮은 Tick 주파수를 설정하면 긴급 상황에서의 응답성이 저하된다.
적응적 Tick 주기는 이러한 딜레마를 해결하기 위한 접근법으로, 다음과 같은 상황에서 특히 유용하다.
- 환경의 동적 특성이 시간에 따라 크게 변화하는 경우
- 계산 자원이 제한되어 있어 항상 높은 Tick 주파수를 유지할 수 없는 경우
- 배터리 구동 로봇에서 전력 소비를 최소화해야 하는 경우
- 임무의 단계에 따라 의사 결정의 긴급성이 달라지는 경우
3. 상태 기반 적응 전략
가장 직관적인 적응 전략은 로봇의 현재 동작 상태에 따라 Tick 주파수를 전환하는 것이다. 로봇의 동작 상태를 유한한 모드(mode)로 분류하고, 각 모드에 적합한 Tick 주파수를 사전에 정의한다.
| 동작 모드 | Tick 주파수 | 근거 |
|---|---|---|
| 대기 (Idle) | 1-2 Hz | 환경 변화가 거의 없음 |
| 순항 (Cruising) | 10-20 Hz | 안정적 이동, 중간 수준의 감시 필요 |
| 장애물 근접 (Near Obstacle) | 30-50 Hz | 빠른 회피 결정 요구 |
| 비상 (Emergency) | 50-100 Hz | 즉각적 반응 필수 |
| 충전 중 (Charging) | 0.5-1 Hz | 최소한의 상태 확인만 필요 |
모드 전환은 블랙보드에 기록된 상태 변수나 조건 노드의 평가 결과에 기반하여 결정된다. 다음은 상태 기반 적응의 구현 예시이다.
double determine_tick_rate(const BT::Blackboard& bb) {
auto mode = bb.get<std::string>("robot_mode");
if (mode == "emergency") return 100.0;
if (mode == "near_obstacle") return 50.0;
if (mode == "cruising") return 15.0;
if (mode == "idle") return 2.0;
return 10.0; // 기본값
}
4. 부하 기반 적응 전략
시스템의 CPU 부하에 따라 Tick 주파수를 조정하는 전략이다. CPU 사용률이 높아지면 Tick 주파수를 낮추어 행동 트리 실행이 다른 서브시스템의 성능을 저해하지 않도록 하고, CPU 여유가 충분하면 Tick 주파수를 높여 응답성을 극대화한다.
f_{tick}(t) = f_{max} \times (1 - U_{other}(t)) \times \alpha
여기서 f_{max}는 허용 가능한 최대 Tick 주파수, U_{other}(t)는 행동 트리를 제외한 다른 서브시스템의 CPU 사용률, \alpha는 안전 계수(0 < \alpha < 1)이다. 이 수식은 다른 서브시스템의 부하가 증가할수록 행동 트리의 Tick 주파수를 감소시키며, 총 CPU 사용률이 과도하게 높아지는 것을 방지한다.
부하 기반 적응 시에는 Tick 주파수의 변동이 지나치게 빈번하면 시스템의 동작이 불안정해질 수 있으므로, 저역 통과 필터(low-pass filter)를 적용하여 주파수 변경을 평활화(smoothing)하는 것이 권장된다.
5. 이벤트 기반 적응 전략
특정 이벤트의 발생을 기점으로 Tick 주파수를 일시적으로 변경하는 전략이다. 예를 들어, 새로운 장애물이 감지되면 Tick 주파수를 즉시 높이고, 일정 시간이 경과하여 위험이 해소되면 원래의 Tick 주파수로 복귀한다.
class AdaptiveTickController {
void on_obstacle_detected() {
set_tick_rate(50.0); // 즉시 고주파로 전환
cooldown_timer_ = std::chrono::seconds(5);
}
void on_tick_completed() {
if (cooldown_timer_ <= std::chrono::seconds(0)
&& !is_obstacle_near()) {
set_tick_rate(default_rate_); // 기본 주파수로 복귀
}
cooldown_timer_ -= tick_period_;
}
double default_rate_ = 10.0;
std::chrono::duration<double> cooldown_timer_;
std::chrono::duration<double> tick_period_;
};
이벤트 기반 적응은 상태 기반 적응과 결합하여 사용할 수 있으며, 이벤트가 모드 전환을 유발하고 모드에 따라 Tick 주파수가 결정되는 계층적 구조가 가능하다.
6. Tick 실행 시간 기반 적응 전략
이전 Tick의 실행 시간을 측정하여, 실행 시간이 짧으면 Tick 주파수를 높이고 실행 시간이 길면 Tick 주파수를 낮추는 전략이다. 이 방법은 행동 트리의 활성 경로(active path)에 따라 실행 시간이 가변적인 경우에 유용하다.
T_{tick}^{(k+1)} = \max\left(T_{min}, \beta \times T_{exec}^{(k)}\right)
여기서 T_{tick}^{(k+1)}은 다음 Tick 주기, T_{exec}^{(k)}는 현재 Tick의 실행 시간, \beta는 안전 배수(safety multiplier, \beta > 1), T_{min}은 허용 가능한 최소 Tick 주기이다. \beta가 클수록 Tick 오버런에 대한 안전 여유가 커지지만, Tick 주파수가 보수적으로 설정된다.
7. 다단계 적응 아키텍처
복잡한 로봇 시스템에서는 복수의 적응 기준을 계층적으로 조합하는 다단계 적응 아키텍처가 효과적이다.
[최상위] 안전 제약 → 최소 Tick 주파수 보장
↓
[중간층] 임무 상태 기반 → 목표 Tick 주파수 결정
↓
[최하위] CPU 부하 기반 → 실현 가능한 Tick 주파수로 조정
최상위 계층은 안전 관련 최소 Tick 주파수를 보장하며, 어떤 상황에서도 이 하한을 위반하지 않는다. 중간 계층은 임무 단계와 환경 조건에 따라 목표 Tick 주파수를 설정하고, 최하위 계층은 시스템의 실제 계산 부하를 고려하여 실현 가능한 범위 내에서 최종 Tick 주파수를 결정한다.
f_{tick} = \max\left(f_{safety}, \min\left(f_{mission}, f_{load}\right)\right)
8. 히스테리시스를 통한 안정화
Tick 주파수의 적응 과정에서 경계 조건 근처에서 주파수가 빈번하게 진동(oscillation)하는 현상을 방지하기 위해 히스테리시스(hysteresis)를 적용한다. 히스테리시스는 모드 전환의 상향 임계값과 하향 임계값을 분리하여, 미세한 상태 변동이 반복적인 모드 전환을 유발하지 않도록 한다.
예를 들어, 장애물 거리 기준으로 Tick 주파수를 전환하는 경우:
- 상향 전환 (고주파로): 장애물 거리 < 3.0m 일 때
- 하향 전환 (저주파로): 장애물 거리 > 5.0m 일 때
3.0m와 5.0m 사이의 구간에서는 현재 모드가 유지되므로, 장애물 거리가 경계 근처에서 진동하더라도 Tick 주파수는 안정적으로 유지된다.
9. 적응적 Tick 주기의 설계 시 고려 사항
적응적 Tick 주기를 설계할 때에는 다음 사항을 고려해야 한다.
9.1 최소 Tick 주파수의 보장
어떤 적응 전략을 사용하더라도, 시스템의 안전성과 기본적인 기능 수행을 위해 필요한 최소 Tick 주파수를 항상 보장해야 한다. 적응 로직의 결함이나 예외적 상황으로 인해 Tick 주파수가 0으로 감소하거나 극단적으로 낮아지는 것을 방지하는 안전 장치(failsafe)가 필요하다.
9.2 전환 지연의 관리
Tick 주파수의 변경이 실제로 적용되기까지의 지연을 관리해야 한다. ROS2 타이머의 교체, 스케줄러의 재설정 등 Tick 주파수 변경에 수반되는 오버헤드가 존재하며, 이 오버헤드가 짧은 Tick 주기보다 클 경우 의도한 적응 효과가 상쇄될 수 있다.
9.3 검증과 테스트의 복잡도
적응적 Tick 주기는 시스템의 동작이 Tick 주파수 자체의 변화에 의해서도 영향을 받으므로, 고정 Tick 주기에 비해 검증과 테스트의 복잡도가 증가한다. 모든 적응 시나리오에 대한 체계적인 테스트와, 경계 조건에서의 동작 검증이 필수적이다.
9.4 재현성의 저하
적응적 Tick 주기를 사용하는 시스템은 동일한 입력에 대해서도 CPU 부하 등의 외부 요인에 따라 다른 Tick 패턴을 생성할 수 있다. 이는 디버깅과 문제 재현을 어렵게 만들므로, 적응 결정 과정을 포함한 상세한 로깅이 필요하다.
참고 문헌
- 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/