사무실 안내·순찰 로봇 핵심 노드 상세설계서 작성 예시 #2

19. 이동 실패 처리

19.1 이동 실패 조건

다음 Nav2 결과를 이동 실패로 처리한다.

ABORTED
CANCELED
UNKNOWN
목표 수락 거부
이동 제한시간 초과
Nav2 서버 연결 해제

사용자 일시정지, 이상 이벤트 및 비상정지에 의한 목표 취소는 일반 이동 실패 횟수에 포함하지 않는다.

19.2 이동 실패 처리 절차

이동 실패 발생
    ↓
실패 원인 확인
    ↓
사용자 중지 또는 비상정지인가?
    ├─ 예 → 재시도하지 않음
    └─ 아니오
         ↓
      재시도 횟수 증가
         ↓
      최대 재시도 이하인가?
         ├─ 예 → 재시도 대기 후 현재 목표 재전송
         └─ 아니오
              ↓
           실패 로그 저장
              ↓
           continue_on_failure 확인
              ├─ true → 다음 지점 이동
              └─ false → 순찰 종료 및 ERROR 전환

19.3 재시도 처리

이동 실패 시 다음과 같이 재시도 횟수를 증가시킨다.

retry_count_++;

재시도 횟수가 최대 재시도 횟수 이하이면 다음 작업을 수행한다.

  1. 상태를 RETRY_WAIT로 변경한다.
  2. GOAL_RETRY 이벤트를 발행한다.
  3. retry_delay_sec 동안 대기한다.
  4. 동일한 순찰 지점을 다시 Nav2 목표로 전송한다.

판단 조건은 다음과 같다.

if (retry_count_ <= max_retry_count_)
{
  scheduleRetry();
}

19.4 최대 재시도 초과 처리

최대 재시도 횟수를 초과하면 다음 작업을 수행한다.

  1. 현재 지점 상태를 FAILED로 발행한다.
  2. GOAL_FAILED 이벤트를 발행한다.
  3. 실패 원인과 시각을 로그로 저장한다.
  4. retry_count_를 0으로 초기화한다.
  5. continue_on_failure 값을 확인한다.

continue_on_failure가 true이면 현재 지점을 건너뛰고 다음 지점으로 이동한다.

continue_on_failure가 false이면 순찰을 종료하고 상태를 ERROR로 변경한다.

20. 이상 이벤트 처리

20.1 이상 이벤트 발생

severity가 2 이상이고 active가 true이면 다음 작업을 수행한다.

  1. 이상 이벤트 ID를 저장한다.
  2. paused_by_anomaly_를 true로 설정한다.
  3. 현재 Nav2 목표를 취소한다.
  4. 대기 타이머를 중지한다.
  5. 현재 순찰 지점 번호를 유지한다.
  6. 재시도 횟수를 유지한다.
  7. 상태를 PAUSED_ANOMALY로 변경한다.
  8. ANOMALY_DETECTED 이벤트를 발행한다.
  9. 원격 GUI에 관리자 확인 필요 상태를 표시한다.

20.2 이상 이벤트 해제

동일한 이상 이벤트 ID에 대해 active가 false로 수신되면 다음 작업을 수행한다.

  1. paused_by_anomaly_를 false로 설정한다.
  2. 이상 이벤트 ID를 초기화한다.
  3. ANOMALY_CLEARED 이벤트를 발행한다.
  4. auto_resume_after_anomaly 값을 확인한다.

auto_resume_after_anomaly가 true이면 현재 순찰 지점부터 자동 재개한다.

auto_resume_after_anomaly가 false이면 관리자의 재개 요청을 기다린다.

21. 배터리 부족 처리

21.1 순찰 시작 배터리 기준

배터리 잔량이 start_battery_threshold보다 낮으면 순찰 시작을 허용하지 않는다.

기본값은 다음과 같다.

40.0%

21.2 순찰 중 배터리 부족

순찰 중 배터리 잔량이 low_battery_threshold 이하가 되면 다음 작업을 수행한다.

  1. low_battery_active_를 true로 설정한다.
  2. 현재 Nav2 목표를 취소한다.
  3. 순찰 지점 대기 타이머를 중지한다.
  4. LOW_BATTERY 이벤트를 발행한다.
  5. 순찰 실행 상태를 해제한다.
  6. 상태를 RETURNING_HOME으로 변경한다.
  7. 대기 위치를 Nav2 목표로 전송한다.

기본값은 다음과 같다.

30.0%

21.3 위험 배터리 처리

배터리 잔량이 critical_battery_threshold 이하가 되면 다음 작업을 수행한다.

  1. 현재 Nav2 목표를 즉시 취소한다.
  2. 로봇 정지 명령을 발행한다.
  3. 자동 복귀를 시도하지 않는다.
  4. 상태를 ERROR로 변경한다.
  5. 원격 GUI에 긴급 충전 요청을 표시한다.

기본값은 다음과 같다.

15.0%

배터리가 위험 수준인 경우 대기 위치까지 이동하는 것보다 현재 위치에서 정지하는 것을 우선한다.

22. 대기 위치 복귀 처리

22.1 복귀 발생 조건

다음 조건에서 대기 위치 복귀를 수행한다.

  • 배터리 부족
  • 순찰 완료
  • 관리자 복귀 명령
  • 설정에 따른 순찰 중지 후 복귀

22.2 복귀 처리 절차

  1. 현재 Nav2 목표를 취소한다.
  2. 순찰 실행 상태를 해제한다.
  3. 상태를 RETURNING_HOME으로 변경한다.
  4. /return_home/request에 true를 발행한다.
  5. 설정 파일의 home_point를 읽는다.
  6. 대기 위치를 Nav2 목표로 전송한다.
  7. 대기 위치 도착 여부를 확인한다.
  8. 도착하면 상태를 STOPPED 또는 COMPLETED로 변경한다.
  9. 복귀 완료 이벤트를 발행한다.

대기 위치 복귀가 실패하면 설정된 max_retry_count만큼 재시도한다.

복귀 재시도까지 실패하면 상태를 ERROR로 변경하고 원격 GUI에 수동 이동 요청을 표시한다.

23. 비상정지 처리

23.1 비상정지 우선순위

비상정지는 모든 명령과 상태보다 우선한다.

이벤트 처리 우선순위는 다음과 같다.

비상정지
배터리 위험
배터리 부족
이상 이벤트
사용자 중지
사용자 일시정지
Nav2 이동 결과
순찰 지점 대기 완료

23.2 비상정지 절차

  1. /emergency_stop에서 true를 수신한다.
  2. emergency_stop_active_를 true로 설정한다.
  3. 현재 Nav2 목표를 취소한다.
  4. 모든 내부 타이머를 중지한다.
  5. patrol_active_를 false로 설정한다.
  6. 상태를 EMERGENCY_STOP으로 변경한다.
  7. /cmd_vel에 0 속도 명령을 반복 발행한다.
  8. EMERGENCY_STOPPED 이벤트를 발행한다.
  9. 순찰 시작 및 재개 요청을 거부한다.

정지 명령은 다음과 같다.

linear.x  = 0.0
linear.y  = 0.0
linear.z  = 0.0
angular.x = 0.0
angular.y = 0.0
angular.z = 0.0

23.3 비상정지 해제

/emergency_stop에서 false를 수신해도 자동으로 순찰을 재개하지 않는다.

비상정지 해제 후 다음 절차를 수행한다.

  1. emergency_stop_active_를 false로 설정한다.
  2. 상태를 STOPPED로 변경한다.
  3. 관리자가 로봇 상태를 확인한다.
  4. 관리자가 순찰 시작 요청을 다시 전송한다.
  5. 첫 번째 순찰 지점부터 새 순찰을 시작한다.

24. 사용자 중지 처리

순찰 중지 요청이 발생하면 다음 작업을 수행한다.

  1. 현재 Nav2 목표를 취소한다.
  2. 대기 타이머를 중지한다.
  3. patrol_active_를 false로 설정한다.
  4. paused_by_user_를 false로 설정한다.
  5. paused_by_anomaly_를 false로 설정한다.
  6. retry_count_를 0으로 초기화한다.
  7. 상태를 STOPPED로 변경한다.
  8. PATROL_STOPPED 이벤트를 발행한다.

return_home_on_stop이 true이면 대기 위치 복귀 절차를 수행한다.

25. 원격 PC GUI 연동

25.1 GUI 기능

원격 PC GUI는 다음 기능을 제공한다.

  • 순찰 시작
  • 순찰 중지
  • 순찰 일시정지
  • 순찰 재개
  • 현재 로봇 위치 표시
  • 순찰 지점 표시
  • 현재 목표 지점 강조
  • 순찰 상태 표시
  • 완료한 순찰 횟수 표시
  • 배터리 잔량 표시
  • 이상 이벤트 표시
  • Nav2 이동 실패 표시
  • 비상정지 상태 표시
  • 로그 표시

25.2 GUI 명령 연결

GUI 버튼호출 인터페이스
순찰 시작/patrol_manager/start
순찰 중지/patrol_manager/stop
일시정지/patrol_manager/pause
순찰 재개/patrol_manager/resume
비상정지/emergency_stop에 true 발행
비상정지 해제/emergency_stop에 false 발행

25.3 GUI 상태 표시

GUI는 /patrol_manager/status를 구독하여 상태를 표시한다.

상태별 표시 문구는 다음과 같다.

상태GUI 표시
IDLE순찰 대기
VALIDATING시작 조건 확인 중
NAVIGATING순찰 지점 이동 중
WAITING순찰 지점 점검 중
PAUSED_USER사용자 일시정지
PAUSED_ANOMALY이상 감지로 일시정지
RETRY_WAIT이동 재시도 대기
RETURNING_HOME대기 위치 복귀 중
COMPLETED순찰 완료
STOPPED순찰 중지
ERROR오류 발생
EMERGENCY_STOP비상정지

25.4 통신 단절 처리

원격 PC와 터틀봇3 사이의 네트워크가 끊어져도 patrol_manager는 로봇 내부에서 계속 실행된다.

통신 단절 시 처리 기준은 다음과 같다.

  1. GUI 상태 갱신이 중단된다.
  2. 현재 순찰은 로봇 내부에서 계속 수행한다.
  3. 비상정지와 배터리 부족 처리는 계속 수행한다.
  4. 네트워크가 복구되면 최신 상태를 GUI에 다시 전송한다.
  5. 상태 토픽은 transient_local QoS를 사용하여 늦게 연결된 GUI가 최신 상태를 수신하도록 한다.

26. QoS 설계

인터페이스ReliabilityDurabilityHistory
/patrol_manager/statusReliableTransient LocalKeep Last 1
/patrol_manager/current_pointReliableTransient LocalKeep Last 1
/patrol_manager/eventReliableVolatileKeep Last 50
/patrol_manager/logReliableVolatileKeep Last 100
/battery_stateReliableVolatileKeep Last 10
/anomaly_eventReliableVolatileKeep Last 20
/emergency_stopReliableTransient LocalKeep Last 1
/operation_modeReliableTransient LocalKeep Last 1
/cmd_velReliableVolatileKeep Last 10

27. 콜백 및 실행 구조

27.1 콜백 그룹

상태 변경 충돌을 방지하기 위해 콜백 그룹을 구분한다.

콜백 그룹유형포함 기능
state_callback_group_Mutually Exclusive시작, 중지, 일시정지, 재개
nav_callback_group_ReentrantNav2 목표 응답, 피드백, 결과
safety_callback_group_Mutually Exclusive배터리, 이상 이벤트, 비상정지
timer_callback_group_Mutually Exclusive상태 발행, 배터리 검사, 대기 타이머

27.2 Executor

다음 Executor 사용을 기본으로 한다.

rclcpp::executors::MultiThreadedExecutor

상태를 변경하는 모든 함수에서는 mutex를 사용하여 내부 변수의 동시 접근을 방지한다.

std::mutex state_mutex_;

28. 주요 처리 의사코드

28.1 순찰 시작

bool PatrolManager::startPatrol()
{
  std::lock_guard<std::mutex> lock(state_mutex_);

  changeState(PatrolState::VALIDATING);

  if (!validateStartConditions()) {
    changeState(PatrolState::IDLE);
    return false;
  }

  current_index_ = 0;
  completed_cycles_ = 0;
  retry_count_ = 0;
  patrol_active_ = true;
  paused_by_user_ = false;
  paused_by_anomaly_ = false;
  patrol_start_time_ = now();

  publishEvent("PATROL_STARTED", "", "Patrol started", 0);
  sendCurrentGoal();

  return true;
}

28.2 현재 순찰 지점 전송

void PatrolManager::sendCurrentGoal()
{
  if (!patrol_active_) {
    return;
  }

  if (current_index_ < 0 ||
      current_index_ >= static_cast<int>(patrol_points_.size())) {
    changeState(PatrolState::ERROR);
    return;
  }

  const auto & point = patrol_points_.at(current_index_);

  current_goal_id_ = point.id;
  retry_count_ = std::max(retry_count_, 0);

  publishCurrentPoint(point, "MOVING");
  publishEvent("GOAL_SENT", point.id, "Navigation goal sent", 0);

  sendGoal(point);
  changeState(PatrolState::NAVIGATING);
}

28.3 이동 성공

void PatrolManager::handleNavigationSuccess()
{
  goal_in_progress_ = false;
  retry_count_ = 0;
  point_arrival_time_ = now();

  const auto & point = patrol_points_.at(current_index_);

  publishCurrentPoint(point, "ARRIVED");
  publishEvent("GOAL_REACHED", point.id, "Patrol point reached", 0);

  startPointWait(point.wait_time_sec);
}

28.4 이동 실패

void PatrolManager::handleNavigationFailure(
  const std::string & reason)
{
  goal_in_progress_ = false;
  last_nav_result_ = reason;

  if (emergency_stop_active_ ||
      paused_by_user_ ||
      paused_by_anomaly_ ||
      !patrol_active_) {
    return;
  }

  retry_count_++;

  if (retry_count_ <= max_retry_count_) {
    changeState(PatrolState::RETRY_WAIT);
    publishEvent(
      "GOAL_RETRY",
      current_goal_id_,
      "Retry navigation: " + std::to_string(retry_count_),
      1);

    scheduleRetry();
    return;
  }

  publishCurrentPoint(
    patrol_points_.at(current_index_),
    "FAILED");

  publishEvent(
    "GOAL_FAILED",
    current_goal_id_,
    reason,
    2);

  retry_count_ = 0;

  if (continue_on_failure_) {
    advanceToNextPoint();
  } else {
    patrol_active_ = false;
    changeState(PatrolState::ERROR);
  }
}

28.5 다음 지점 이동

void PatrolManager::advanceToNextPoint()
{
  current_index_++;

  if (current_index_ < static_cast<int>(patrol_points_.size())) {
    sendCurrentGoal();
    return;
  }

  completePatrolCycle();
}

28.6 순찰 1회 완료

void PatrolManager::completePatrolCycle()
{
  completed_cycles_++;

  publishEvent(
    "CYCLE_COMPLETED",
    "",
    "Patrol cycle completed",
    0);

  if (patrol_repeat_count_ == 0 ||
      completed_cycles_ < patrol_repeat_count_) {
    current_index_ = 0;
    sendCurrentGoal();
    return;
  }

  patrol_active_ = false;
  changeState(PatrolState::COMPLETED);

  publishEvent(
    "PATROL_COMPLETED",
    "",
    "All patrol cycles completed",
    0);

  if (return_home_on_complete_) {
    requestReturnHome();
  }
}

29. 로그 설계

29.1 로그 레벨

로그 레벨사용 조건
DEBUG내부 상태, 인덱스, 타이머 정보
INFO순찰 시작, 목표 전송, 도착, 순찰 완료
WARN이동 재시도, 배터리 부족 접근, 이상 이벤트
ERROR목표 실패, 설정 파일 오류, Nav2 연결 실패
FATAL노드 실행을 계속할 수 없는 초기화 오류

29.2 주요 로그 형식

[PATROL][START] cycle=0 point=P01
[PATROL][GOAL_SENT] index=0 id=P01 x=1.20 y=0.50 yaw=0.00
[PATROL][ARRIVED] index=0 id=P01
[PATROL][RETRY] index=1 id=P02 retry=1 reason=ABORTED
[PATROL][FAILED] index=1 id=P02 reason=TIMEOUT
[PATROL][CYCLE_COMPLETED] completed_cycles=1
[PATROL][LOW_BATTERY] battery=29.5
[PATROL][RETURN_HOME] id=HOME
[PATROL][EMERGENCY_STOP] source=/emergency_stop

29.3 로그 저장 항목

다음 항목을 파일 로그 또는 rosbag에 저장할 수 있다.

  • 순찰 시작 및 종료 시각
  • 각 지점 목표 전송 시각
  • 각 지점 도착 시각
  • 지점별 이동 소요시간
  • 이동 실패 원인
  • 재시도 횟수
  • 이상 이벤트 발생 시각
  • 배터리 부족 발생 시각
  • 대기 위치 복귀 결과
  • 비상정지 발생 시각

30. 파일 구성

turtlebot3_patrol/
├── CMakeLists.txt
├── package.xml
├── include/
│   └── turtlebot3_patrol/
│       └── patrol_manager.hpp
├── src/
│   ├── patrol_manager.cpp
│   └── patrol_manager_main.cpp
├── config/
│   ├── patrol_manager.yaml
│   └── patrol_points.yaml
├── launch/
│   ├── patrol_manager.launch.py
│   └── turtlebot3_patrol_system.launch.py
├── test/
│   ├── test_patrol_manager.cpp
│   ├── test_patrol_points.cpp
│   └── test_patrol_state.cpp
└── README.md

31. Launch 설계

31.1 Launch 파일

파일명은 다음과 같다.

patrol_manager.launch.py

31.2 Launch 구성 예시

from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node
from ament_index_python.packages import get_package_share_directory

import os


def generate_launch_description():
    package_share = get_package_share_directory('turtlebot3_patrol')

    default_param_file = os.path.join(
        package_share,
        'config',
        'patrol_manager.yaml'
    )

    param_file_arg = DeclareLaunchArgument(
        'params_file',
        default_value=default_param_file
    )

    patrol_manager_node = Node(
        package='turtlebot3_patrol',
        executable='patrol_manager_node',
        name='patrol_manager',
        output='screen',
        parameters=[
            LaunchConfiguration('params_file')
        ],
        respawn=True,
        respawn_delay=3.0
    )

    return LaunchDescription([
        param_file_arg,
        patrol_manager_node
    ])

32. 실행 절차

32.1 터틀봇3 내부 SBC

터틀봇3 Bringup을 실행한다.

export TURTLEBOT3_MODEL=burger
export ROS_DOMAIN_ID=30

ros2 launch turtlebot3_bringup robot.launch.py

Nav2를 실행한다.

ros2 launch turtlebot3_navigation2 navigation2.launch.py \
  use_sim_time:=False \
  map:=$HOME/maps/patrol_map.yaml

순찰 관리 노드를 실행한다.

ros2 launch turtlebot3_patrol patrol_manager.launch.py

32.2 원격 PC

원격 PC에 동일한 ROS Domain ID를 설정한다.

export TURTLEBOT3_MODEL=burger
export ROS_DOMAIN_ID=30

RViz2를 실행한다.

ros2 launch turtlebot3_navigation2 rviz2.launch.py

GUI 프로그램을 실행한다.

ros2 run turtlebot3_patrol_gui patrol_gui

33. 서비스 시험 명령

순찰 시작 명령은 다음과 같다.

ros2 service call /patrol_manager/start std_srvs/srv/Trigger "{}"

순찰 중지 명령은 다음과 같다.

ros2 service call /patrol_manager/stop std_srvs/srv/Trigger "{}"

순찰 일시정지 명령은 다음과 같다.

ros2 service call /patrol_manager/pause std_srvs/srv/Trigger "{}"

순찰 재개 명령은 다음과 같다.

ros2 service call /patrol_manager/resume std_srvs/srv/Trigger "{}"

34. 토픽 시험 명령

운용 모드를 순찰 모드로 설정한다.

ros2 topic pub --once /operation_mode std_msgs/msg/String \
  "{data: 'PATROL'}"

이상 이벤트를 발생시킨다.

ros2 topic pub --once /anomaly_event \
  turtlebot3_patrol_msgs/msg/AnomalyEvent \
  "{
    event_id: 'ANOMALY_001',
    event_type: 'PERSON_DETECTED',
    severity: 2,
    active: true,
    description: 'Unknown person detected'
  }"

이상 이벤트를 해제한다.

ros2 topic pub --once /anomaly_event \
  turtlebot3_patrol_msgs/msg/AnomalyEvent \
  "{
    event_id: 'ANOMALY_001',
    event_type: 'PERSON_DETECTED',
    severity: 2,
    active: false,
    description: 'Anomaly cleared'
  }"

비상정지를 발생시킨다.

ros2 topic pub --once /emergency_stop std_msgs/msg/Bool \
  "{data: true}"

비상정지를 해제한다.

ros2 topic pub --once /emergency_stop std_msgs/msg/Bool \
  "{data: false}"

순찰 상태를 확인한다.

ros2 topic echo /patrol_manager/status

35. 단위시험 항목

35.1 순찰 지점 파일 시험

시험 항목입력 조건예상 결과
정상 파일 읽기유효한 YAML 파일모든 순찰 지점 로드
파일 없음존재하지 않는 경로노드 상태 ERROR
순찰 지점 없음빈 목록순찰 시작 거부
필수 좌표 누락x 또는 y 없음설정 오류 처리
중복 ID동일 ID 2개설정 오류 처리
잘못된 대기시간음수 값설정 오류 처리
대기 위치 누락home_point 없음복귀 기능 비활성 또는 초기화 실패

35.2 순찰 시작 시험

시험 항목입력 조건예상 결과
정상 순찰 시작모드 정상, 배터리 정상첫 지점 목표 전송
잘못된 운용 모드MANUAL시작 요청 거부
배터리 부족시작 기준 미만시작 요청 거부
비상정지 상태비상정지 활성시작 요청 거부
Nav2 미실행액션 서버 없음시작 요청 거부
순찰 중 재시작이미 실행 중중복 시작 거부

35.3 순찰 지점 전환 시험

시험 항목시험 내용예상 결과
첫 순찰 지점 선택순찰 시작P01 선택
다음 순찰 지점 전환P01 도착 및 대기 완료P02 선택
마지막 지점 처리마지막 지점 완료순찰 횟수 증가
첫 지점 복귀다음 순찰 반복P01 재선택
지점 대기시간지점 도착설정 시간 동안 WAITING
대기시간 0지점 도착즉시 다음 지점 이동

35.4 순찰 횟수 시험

시험 항목설정예상 결과
1회 순찰patrol_repeat_count=11회 후 완료
3회 순찰patrol_repeat_count=33회 후 완료
무한 순찰patrol_repeat_count=0중지 전까지 반복
순찰 횟수 증가마지막 지점 완료completed_cycles_ 증가

35.5 이동 실패 시험

시험 항목입력 조건예상 결과
1회 이동 실패재시도 가능동일 목표 재전송
최대 재시도 이하실패 2회재시도 수행
최대 재시도 초과실패 3회 이상실패 로그 저장
실패 후 계속continue_on_failure=true다음 지점 이동
실패 후 종료continue_on_failure=false상태 ERROR
사용자 취소일시정지 요청실패 횟수 증가 없음
이동 제한시간 초과제한시간 초과이동 실패 처리

35.6 이상 이벤트 시험

시험 항목입력 조건예상 결과
이상 이벤트 발생severity=2, active=true순찰 일시정지
위험 이벤트 발생severity=3목표 취소 및 관리자 확인
정보 이벤트 발생severity=0로그만 저장
이상 이벤트 해제active=false재개 가능 상태
관리자 재개 요청이상 해제 후 resume현재 지점 재전송
자동 재개자동 재개 활성이상 해제 후 자동 이동

35.7 배터리 시험

시험 항목입력 조건예상 결과
배터리 정상80%순찰 계속
시작 기준 미만35%순찰 시작 거부
복귀 기준 이하29%순찰 종료 및 복귀
위험 기준 이하14%즉시 정지
복귀 중 목표 성공대기 위치 도착STOPPED
복귀 중 목표 실패최대 재시도 초과ERROR

35.8 비상정지 시험

시험 항목입력 조건예상 결과
이동 중 비상정지true 수신목표 즉시 취소
대기 중 비상정지true 수신대기 타이머 중지
비상정지 상태 시작 요청start 호출요청 거부
비상정지 해제false 수신자동 재개하지 않음
정지 속도 발행비상정지 발생0 속도 반복 발행

35.9 사용자 제어 시험

시험 항목입력 조건예상 결과
순찰 일시정지pause 호출현재 목표 취소
일시정지 후 재개resume 호출현재 지점 재전송
순찰 중지stop 호출상태 STOPPED
중지 후 재시작start 호출첫 지점부터 시작
완료 후 재시작start 호출순찰 횟수 초기화

35.10 원격 GUI 시험

시험 항목시험 내용예상 결과
상태 표시상태 토픽 구독현재 상태 표시
현재 지점 표시지점 토픽 구독현재 목표 강조
배터리 표시상태 메시지 확인배터리 잔량 표시
이동 실패 표시실패 이벤트 발생GUI 경고 표시
비상정지 표시비상정지 발생긴급 상태 표시
GUI 재접속실행 중 GUI 재시작최신 상태 즉시 수신
네트워크 복구통신 단절 후 재연결상태 갱신 재개

36. 통합시험 시나리오

36.1 정상 순찰 시나리오

  1. 터틀봇3 Bringup을 실행한다.
  2. Nav2와 AMCL을 실행한다.
  3. 초기 위치를 설정한다.
  4. 운용 모드를 PATROL로 설정한다.
  5. GUI에서 순찰 시작 버튼을 누른다.
  6. 첫 번째 순찰 지점으로 이동하는지 확인한다.
  7. 지점 도착 후 설정된 시간 동안 대기하는지 확인한다.
  8. 다음 지점으로 이동하는지 확인한다.
  9. 마지막 지점 완료 후 순찰 횟수가 증가하는지 확인한다.
  10. 설정된 반복 횟수 완료 후 대기 위치로 복귀하는지 확인한다.

36.2 이동 실패 시나리오

  1. 순찰을 시작한다.
  2. 현재 목표 앞에 장애물을 배치한다.
  3. Nav2가 복구 동작을 수행하는지 확인한다.
  4. 이동 실패 결과가 발생하는지 확인한다.
  5. 동일 지점을 재시도하는지 확인한다.
  6. 최대 재시도 초과 후 다음 지점으로 이동하는지 확인한다.
  7. 실패 이벤트가 GUI에 표시되는지 확인한다.

36.3 이상 이벤트 시나리오

  1. 순찰 중 이상 이벤트를 발생시킨다.
  2. 현재 Nav2 목표가 취소되는지 확인한다.
  3. 상태가 PAUSED_ANOMALY로 변경되는지 확인한다.
  4. GUI에 이상 이벤트가 표시되는지 확인한다.
  5. 이상 이벤트를 해제한다.
  6. 관리자 재개 요청을 전송한다.
  7. 중단된 순찰 지점부터 다시 이동하는지 확인한다.

36.4 배터리 부족 시나리오

  1. 순찰을 시작한다.
  2. 배터리 잔량을 복귀 기준 이하로 입력한다.
  3. 현재 순찰 목표가 취소되는지 확인한다.
  4. 상태가 RETURNING_HOME으로 변경되는지 확인한다.
  5. 대기 위치가 Nav2 목표로 전송되는지 확인한다.
  6. 대기 위치 도착 후 순찰이 종료되는지 확인한다.

36.5 비상정지 시나리오

  1. 터틀봇3가 순찰 지점으로 이동하도록 한다.
  2. GUI에서 비상정지 버튼을 누른다.
  3. Nav2 목표가 즉시 취소되는지 확인한다.
  4. 로봇이 정지하는지 확인한다.
  5. 상태가 EMERGENCY_STOP으로 변경되는지 확인한다.
  6. 비상정지를 해제한다.
  7. 자동으로 이동하지 않는지 확인한다.
  8. 새 순찰 시작 요청 후 첫 지점부터 이동하는지 확인한다.

37. 완료 기준

patrol_manager는 다음 조건을 모두 만족하면 개발 완료로 판단한다.

  1. YAML 파일에서 순찰 지점을 정상적으로 불러온다.
  2. 원격 PC GUI에서 순찰 시작과 중지가 가능하다.
  3. 첫 번째 지점부터 마지막 지점까지 순서대로 이동한다.
  4. 각 지점에서 설정된 시간 동안 대기한다.
  5. 마지막 지점 완료 후 순찰 횟수가 증가한다.
  6. 지정된 횟수만큼 순찰을 반복한다.
  7. 이동 실패 시 설정된 횟수만큼 재시도한다.
  8. 최대 재시도 초과 시 설정에 따라 다음 지점으로 이동하거나 순찰을 종료한다.
  9. 이상 이벤트 발생 시 현재 이동을 중지하고 순찰을 일시정지한다.
  10. 이상 이벤트 해제 후 관리자 요청으로 순찰을 재개한다.
  11. 배터리 부족 시 현재 순찰을 종료하고 대기 위치로 복귀한다.
  12. 위험 배터리 상태에서는 현재 위치에서 즉시 정지한다.
  13. 비상정지 발생 시 모든 순찰 동작을 즉시 중지한다.
  14. 비상정지 해제 후 자동으로 순찰을 재개하지 않는다.
  15. 원격 PC GUI에서 현재 상태, 현재 지점, 배터리 및 오류를 확인할 수 있다.
  16. 네트워크 재연결 후 GUI가 최신 순찰 상태를 다시 수신한다.
  17. 모든 단위시험과 통합시험을 통과한다.

Leave a Comment