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

1.1 문서 목적

본 문서는 터틀봇3 버거를 이용한 실내 자율 순찰 시스템의 핵심 노드인 patrol_manager의 상세설계를 정의한다.

patrol_manager는 설정 파일에 등록된 순찰 지점을 순서대로 이동하며 다음 기능을 수행한다.

  • 순찰 시작, 중지, 일시정지 및 재개
  • Nav2 이동 목표 전송
  • 현재 순찰 지점 관리
  • 순찰 반복 횟수 관리
  • 이동 실패 재시도
  • 이상 이벤트 발생 시 일시정지
  • 배터리 부족 시 대기 위치 복귀
  • 비상정지 처리
  • 원격 PC GUI에 순찰 상태 전송

본 설계서는 ROS 2 노드의 클래스 구조, 토픽, 서비스, 액션, 파라미터, 상태 전이, 예외 처리 및 단위시험 항목을 포함한다.

2. 적용 시스템

2.1 대상 로봇

항목내용
로봇TurtleBot3 Burger
구동 방식차동 구동형 모바일 로봇
주행 제어ROS 2 Navigation2
위치 추정AMCL
지도SLAM으로 작성된 2차원 지도
거리 센서2D LiDAR
로봇 제어 컴퓨터터틀봇3 내부 SBC
사용자 인터페이스원격 PC GUI
통신 방식무선 네트워크 기반 ROS 2 DDS 통신

2.2 시스템 실행 구성

터틀봇3 내부 SBC에서는 다음 프로그램을 실행한다.

  • TurtleBot3 Bringup
  • LiDAR 드라이버
  • OpenCR 통신 노드
  • Nav2
  • AMCL
  • patrol_manager

원격 PC에서는 다음 프로그램을 실행한다.

  • 순찰 제어 GUI
  • RViz2
  • 지도 및 로봇 위치 표시
  • 순찰 시작, 중지, 일시정지 및 재개 명령 전송
  • 순찰 상태 및 오류 로그 표시

patrol_manager는 네트워크가 일시적으로 끊기더라도 현재 상태를 유지할 수 있도록 터틀봇3 내부 SBC에서 실행하는 것을 기본으로 한다.

3. 모듈명

3.1 노드명

patrol_manager

3.2 패키지명

turtlebot3_patrol

3.3 실행 파일명

patrol_manager_node

3.4 네임스페이스

단일 로봇을 운용하는 경우 기본 네임스페이스를 사용한다.

/patrol_manager

다중 로봇 운용 시 로봇별 네임스페이스를 적용한다.

/tb3_01/patrol_manager
/tb3_02/patrol_manager

4. 목적

patrol_manager는 설정 파일에 정의된 순찰 지점을 순서대로 이동하고, 각 지점의 도착 여부와 대기시간을 관리한다.

주요 목적은 다음과 같다.

  1. 순찰 지점 목록을 설정 파일에서 불러온다.
  2. 순찰 시작 조건을 검사한다.
  3. 현재 순찰 지점을 Nav2 이동 목표로 전송한다.
  4. Nav2 이동 결과를 확인한다.
  5. 이동 성공 시 다음 순찰 지점으로 전환한다.
  6. 이동 실패 시 설정된 횟수만큼 재시도한다.
  7. 마지막 지점 완료 시 순찰 횟수를 증가시킨다.
  8. 지정된 반복 횟수만큼 순찰을 수행한다.
  9. 이상 이벤트 발생 시 이동을 일시정지한다.
  10. 배터리가 부족하면 순찰을 종료하고 대기 위치로 복귀한다.
  11. 비상정지 입력이 발생하면 현재 이동을 즉시 취소한다.
  12. 현재 상태를 원격 PC GUI에 전송한다.

5. 선행 조건

patrol_manager 실행 전 다음 조건이 충족되어야 한다.

  1. 터틀봇3 Bringup이 정상 실행되어야 한다.
  2. LiDAR 데이터가 정상 발행되어야 한다.
  3. 로봇의 오도메트리 데이터가 정상 발행되어야 한다.
  4. 지도 서버가 실행되어야 한다.
  5. AMCL 위치 추정이 완료되어야 한다.
  6. Nav2 서버가 활성화되어야 한다.
  7. 로봇의 초기 위치가 설정되어야 한다.
  8. 순찰 지점 설정 파일이 존재해야 한다.
  9. 터틀봇3와 원격 PC가 동일한 ROS 2 네트워크에 연결되어야 한다.
  10. 원격 PC와 터틀봇3의 ROS_DOMAIN_ID가 동일해야 한다.

6. 입력 인터페이스

6.1 입력 목록

구분인터페이스명자료형설명
서비스/patrol_manager/startstd_srvs/srv/Trigger순찰 시작 요청
서비스/patrol_manager/stopstd_srvs/srv/Trigger순찰 중지 요청
서비스/patrol_manager/pausestd_srvs/srv/Trigger사용자 순찰 일시정지 요청
서비스/patrol_manager/resumestd_srvs/srv/Trigger순찰 재개 요청
토픽/operation_modestd_msgs/msg/String현재 로봇 운용 모드
토픽/battery_statesensor_msgs/msg/BatteryState배터리 잔량 및 전압
토픽/anomaly_eventturtlebot3_patrol_msgs/msg/AnomalyEvent이상 이벤트
토픽/emergency_stopstd_msgs/msg/Bool비상정지 상태
액션 결과/navigate_to_posenav2_msgs/action/NavigateToPoseNav2 이동 결과
TF/tf, /tf_statictf2_msgs/msg/TFMessage로봇 위치 및 좌표 변환

6.2 순찰 시작 서비스

서비스명은 다음과 같다.

/patrol_manager/start

서비스 형식은 다음과 같다.

std_srvs/srv/Trigger

순찰 시작 요청을 수신하면 다음 항목을 검사한다.

  1. 현재 상태가 IDLE, STOPPED 또는 COMPLETED인지 확인한다.
  2. 비상정지 상태가 해제되어 있는지 확인한다.
  3. 운용 모드가 순찰 허용 모드인지 확인한다.
  4. 배터리가 순찰 시작 기준 이상인지 확인한다.
  5. Nav2 액션 서버가 사용 가능한지 확인한다.
  6. 순찰 지점이 1개 이상 등록되어 있는지 확인한다.
  7. AMCL 위치가 정상인지 확인한다.

모든 조건이 정상인 경우 서비스 응답은 다음과 같다.

success: true
message: "Patrol started"

조건이 만족되지 않는 경우 서비스 응답은 다음과 같다.

success: false
message: "Patrol start rejected: low battery"

6.3 순찰 중지 서비스

서비스명은 다음과 같다.

/patrol_manager/stop

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

  1. 현재 Nav2 목표를 취소한다.
  2. 대기 타이머를 중지한다.
  3. 재시도 횟수를 초기화한다.
  4. 순찰 실행 상태를 해제한다.
  5. 상태를 STOPPED로 변경한다.
  6. 중지 이벤트를 발행한다.

6.4 순찰 일시정지 서비스

서비스명은 다음과 같다.

/patrol_manager/pause

순찰 일시정지 요청을 수신하면 다음 작업을 수행한다.

  1. 현재 Nav2 목표를 취소한다.
  2. 현재 순찰 지점 번호를 유지한다.
  3. 순찰 횟수를 유지한다.
  4. 상태를 PAUSED_USER로 변경한다.
  5. 일시정지 이벤트를 발행한다.

6.5 순찰 재개 서비스

서비스명은 다음과 같다.

/patrol_manager/resume

재개 요청을 수신하면 다음 조건을 검사한다.

  1. 현재 상태가 PAUSED_USER 또는 PAUSED_ANOMALY인지 확인한다.
  2. 이상 이벤트가 해제되었는지 확인한다.
  3. 비상정지가 해제되었는지 확인한다.
  4. 배터리가 복귀 기준 이상인지 확인한다.
  5. Nav2 액션 서버가 사용 가능한지 확인한다.

조건이 정상인 경우 현재 순찰 지점을 다시 목표로 전송한다.

6.6 운용 모드 입력

토픽명은 다음과 같다.

/operation_mode

허용되는 값은 다음과 같다.

운용 모드설명
IDLE대기 모드
MANUAL수동 조작 모드
PATROL일반 순찰 모드
NIGHT_PATROL야간 순찰 모드
RETURN_HOME대기 위치 복귀 모드
EMERGENCY비상정지 모드

순찰 시작이 허용되는 모드는 다음과 같다.

PATROL
NIGHT_PATROL

6.7 배터리 상태 입력

토픽명은 다음과 같다.

/battery_state

사용 필드는 다음과 같다.

필드사용 목적
percentage배터리 잔량 판단
voltage배터리 전압 이상 판단
power_supply_status충전 상태 확인

percentage 값이 0.0~1.0 범위로 수신되는 경우 백분율로 변환한다.

battery_percentage = percentage × 100.0

배터리 잔량 정보가 제공되지 않는 경우 전압을 이용한 별도 환산 로직을 적용할 수 있다.

6.8 이상 이벤트 입력

토픽명은 다음과 같다.

/anomaly_event

메시지 형식은 다음과 같이 정의한다.

string event_id
string event_type
uint8 severity
bool active
string description
builtin_interfaces/Time detected_time

severity 값은 다음과 같이 정의한다.

값등급처리
0정보로그만 저장
1주의GUI 알림
2경고순찰 일시정지
3위험즉시 정지 및 관리자 확인
4긴급비상정지 처리

6.9 비상정지 입력

토픽명은 다음과 같다.

/emergency_stop

메시지 값이 true이면 다음 작업을 즉시 수행한다.

  1. 현재 Nav2 목표를 취소한다.
  2. 순찰 타이머를 중지한다.
  3. 속도 명령이 계속 발생하지 않도록 상태를 변경한다.
  4. 상태를 EMERGENCY_STOP으로 변경한다.
  5. 순찰 재개 요청을 거부한다.
  6. 비상정지 이벤트를 원격 GUI에 발행한다.

7. 출력 인터페이스

7.1 출력 목록

구분인터페이스명자료형설명
액션 목표/navigate_to_posenav2_msgs/action/NavigateToPoseNav2 이동 목표
토픽/patrol_manager/statusturtlebot3_patrol_msgs/msg/PatrolStatus현재 순찰 상태
토픽/patrol_manager/current_pointturtlebot3_patrol_msgs/msg/PatrolPointStatus현재 순찰 지점
토픽/patrol_manager/eventturtlebot3_patrol_msgs/msg/PatrolEvent순찰 이벤트
토픽/patrol_manager/logstd_msgs/msg/StringGUI 표시용 로그
토픽/return_home/requeststd_msgs/msg/Bool대기 위치 복귀 요청
토픽/cmd_velgeometry_msgs/msg/Twist비상정지 시 정지 명령

7.2 Nav2 이동 목표

Nav2 액션 서버명은 다음과 같다.

/navigate_to_pose

액션 형식은 다음과 같다.

nav2_msgs/action/NavigateToPose

목표 메시지 설정은 다음과 같다.

goal.pose.header.frame_id = "map"
goal.pose.header.stamp = 현재 시각
goal.pose.pose.position.x = 순찰 지점 x 좌표
goal.pose.pose.position.y = 순찰 지점 y 좌표
goal.pose.pose.position.z = 0.0
goal.pose.pose.orientation = yaw를 quaternion으로 변환한 값

7.3 순찰 상태 메시지

토픽명은 다음과 같다.

/patrol_manager/status

메시지 형식은 다음과 같이 정의한다.

std_msgs/Header header
string state
bool patrol_active
bool paused
bool emergency_stop
int32 current_index
int32 total_points
int32 completed_cycles
int32 target_cycles
int32 retry_count
float32 battery_percentage
string current_goal_id
string last_result
string status_message

원격 GUI는 이 메시지를 이용하여 다음 정보를 표시한다.

  • 현재 순찰 상태
  • 현재 순찰 지점
  • 전체 순찰 지점 개수
  • 완료한 순찰 횟수
  • 목표 순찰 횟수
  • 현재 재시도 횟수
  • 배터리 잔량
  • 마지막 이동 결과
  • 오류 메시지

7.4 현재 순찰 지점 메시지

토픽명은 다음과 같다.

/patrol_manager/current_point

메시지 형식은 다음과 같이 정의한다.

std_msgs/Header header
string point_id
int32 point_index
float64 x
float64 y
float64 yaw
float32 wait_time_sec
string point_state

point_state 값은 다음과 같다.

PENDING
MOVING
ARRIVED
WAITING
FAILED
SKIPPED

7.5 순찰 이벤트 메시지

토픽명은 다음과 같다.

/patrol_manager/event

메시지 형식은 다음과 같이 정의한다.

std_msgs/Header header
string event_type
string point_id
string event_code
string description
uint8 severity

event_type 값은 다음과 같다.

PATROL_STARTED
PATROL_STOPPED
PATROL_PAUSED
PATROL_RESUMED
GOAL_SENT
GOAL_REACHED
GOAL_FAILED
GOAL_RETRY
POINT_SKIPPED
CYCLE_COMPLETED
PATROL_COMPLETED
LOW_BATTERY
RETURN_HOME_REQUESTED
ANOMALY_DETECTED
ANOMALY_CLEARED
EMERGENCY_STOPPED

8. 순찰 지점 설정

8.1 순찰 지점 파일

순찰 지점은 YAML 파일로 관리한다.

기본 파일 경로는 다음과 같다.

turtlebot3_patrol/config/patrol_points.yaml

8.2 순찰 지점 파일 형식

patrol_points:
  - id: "P01"
    frame_id: "map"
    x: 1.20
    y: 0.50
    yaw: 0.00
    wait_time_sec: 5.0

  - id: "P02"
    frame_id: "map"
    x: 2.80
    y: 0.50
    yaw: 1.57
    wait_time_sec: 8.0

  - id: "P03"
    frame_id: "map"
    x: 2.80
    y: 2.20
    yaw: 3.14
    wait_time_sec: 5.0

  - id: "P04"
    frame_id: "map"
    x: 1.20
    y: 2.20
    yaw: -1.57
    wait_time_sec: 10.0

home_point:
  id: "HOME"
  frame_id: "map"
  x: 0.30
  y: 0.30
  yaw: 0.00

8.3 순찰 지점 자료구조

struct PatrolPoint
{
  std::string id;
  std::string frame_id;
  double x;
  double y;
  double yaw;
  double wait_time_sec;
};

8.4 순찰 지점 검증

설정 파일을 불러올 때 다음 항목을 검사한다.

  1. patrol_points 항목이 존재하는지 확인한다.
  2. 순찰 지점이 1개 이상인지 확인한다.
  3. 각 지점에 id, x, y, yaw가 존재하는지 확인한다.
  4. 순찰 지점 ID가 중복되지 않는지 확인한다.
  5. wait_time_sec가 0 이상인지 확인한다.
  6. frame_id가 비어 있으면 map을 기본값으로 사용한다.
  7. home_point가 존재하는지 확인한다.
  8. 잘못된 값이 존재하면 노드 초기화를 실패 처리한다.

9. 내부 변수

변수명자료형초기값설명
patrol_points_std::vector<PatrolPoint>빈 목록전체 순찰 위치 목록
home_point_PatrolPoint기본값대기 위치
current_index_int0현재 순찰 위치 번호
completed_cycles_int0완료한 순찰 횟수
retry_count_int0현재 지점 이동 재시도 횟수
patrol_active_boolfalse순찰 실행 상태
paused_by_anomaly_boolfalse이상 이벤트에 의한 일시정지
paused_by_user_boolfalse사용자 요청에 의한 일시정지
emergency_stop_active_boolfalse비상정지 상태
low_battery_active_boolfalse배터리 부족 상태
current_goal_id_std::string빈 문자열현재 이동 목표 ID
current_state_PatrolStateIDLE현재 상태
operation_mode_std::stringIDLE현재 운용 모드
battery_percentage_double100.0현재 배터리 잔량
last_nav_result_std::string빈 문자열마지막 Nav2 이동 결과
goal_in_progress_boolfalseNav2 목표 수행 여부
waiting_at_point_boolfalse순찰 지점 대기 상태
anomaly_event_id_std::string빈 문자열현재 이상 이벤트 ID
patrol_start_time_rclcpp::Time0순찰 시작 시각
point_arrival_time_rclcpp::Time0순찰 지점 도착 시각
last_status_publish_time_rclcpp::Time0마지막 상태 발행 시각
nav_goal_handle_액션 목표 핸들null현재 Nav2 목표 핸들
wait_timer_ROS 2 Timernull순찰 지점 대기 타이머
status_timer_ROS 2 Timernull상태 주기 발행 타이머
battery_check_timer_ROS 2 Timernull배터리 상태 검사 타이머

10. 파라미터

파라미터자료형기본값설명
patrol_points_file문자열config/patrol_points.yaml순찰 지점 설정 파일
default_wait_time_sec실수5.0지점별 대기시간이 없을 때 적용
max_retry_count정수2이동 실패 최대 재시도 횟수
retry_delay_sec실수2.0이동 재시도 전 대기시간
low_battery_threshold실수30.0순찰 종료 및 복귀 기준
critical_battery_threshold실수15.0즉시 이동 중지 기준
start_battery_threshold실수40.0순찰 시작 허용 기준
continue_on_failure불리언true실패 후 다음 지점 이동 여부
patrol_repeat_count정수00이면 무한 반복
allowed_operation_mode문자열 배열PATROL, NIGHT_PATROL순찰 허용 모드
nav_action_name문자열/navigate_to_poseNav2 액션 서버명
nav_server_wait_sec실수5.0액션 서버 연결 대기시간
goal_response_timeout_sec실수5.0목표 수락 응답 제한시간
navigation_timeout_sec실수120.0지점 이동 제한시간
status_publish_rate_hz실수2.0상태 메시지 발행 주기
battery_check_rate_hz실수1.0배터리 검사 주기
auto_resume_after_anomaly불리언false이상 해제 후 자동 재개 여부
return_home_on_stop불리언false사용자 중지 시 대기 위치 복귀 여부
return_home_on_complete불리언true순찰 완료 후 대기 위치 복귀 여부
publish_zero_velocity_on_emergency불리언true비상정지 시 정지 속도 발행 여부
zero_velocity_publish_count정수10비상정지 시 정지 명령 반복 횟수
use_sim_time불리언false시뮬레이션 시간 사용 여부

10.1 파라미터 파일 예시

patrol_manager:
  ros__parameters:
    patrol_points_file: "/home/ubuntu/turtlebot3_ws/src/turtlebot3_patrol/config/patrol_points.yaml"

    default_wait_time_sec: 5.0
    max_retry_count: 2
    retry_delay_sec: 2.0

    start_battery_threshold: 40.0
    low_battery_threshold: 30.0
    critical_battery_threshold: 15.0

    continue_on_failure: true
    patrol_repeat_count: 0

    allowed_operation_mode:
      - "PATROL"
      - "NIGHT_PATROL"

    nav_action_name: "/navigate_to_pose"
    nav_server_wait_sec: 5.0
    goal_response_timeout_sec: 5.0
    navigation_timeout_sec: 120.0

    status_publish_rate_hz: 2.0
    battery_check_rate_hz: 1.0

    auto_resume_after_anomaly: false
    return_home_on_stop: false
    return_home_on_complete: true

    publish_zero_velocity_on_emergency: true
    zero_velocity_publish_count: 10

11. 상태 정의

11.1 상태 목록

enum class PatrolState
{
  IDLE,
  VALIDATING,
  NAVIGATING,
  WAITING,
  PAUSED_USER,
  PAUSED_ANOMALY,
  RETRY_WAIT,
  RETURNING_HOME,
  COMPLETED,
  STOPPED,
  ERROR,
  EMERGENCY_STOP
};

11.2 상태별 설명

상태설명
IDLE순찰 시작 전 대기 상태
VALIDATING순찰 시작 조건 검사 상태
NAVIGATING현재 순찰 지점으로 이동 중
WAITING순찰 지점 도착 후 대기 중
PAUSED_USER사용자 요청으로 일시정지
PAUSED_ANOMALY이상 이벤트로 일시정지
RETRY_WAIT이동 실패 후 재시도 대기
RETURNING_HOME대기 위치로 복귀 중
COMPLETED설정된 순찰 횟수 완료
STOPPED사용자 요청으로 순찰 중지
ERROR복구할 수 없는 오류 발생
EMERGENCY_STOP비상정지 상태

11.3 상태 전이

현재 상태발생 조건다음 상태
IDLE순찰 시작 요청VALIDATING
VALIDATING시작 조건 정상NAVIGATING
VALIDATING시작 조건 실패IDLE
NAVIGATING목표 도착 성공WAITING
NAVIGATING이동 실패 및 재시도 가능RETRY_WAIT
NAVIGATING이동 실패 및 재시도 초과NAVIGATING 또는 ERROR
WAITING대기시간 완료NAVIGATING
NAVIGATING이상 이벤트 발생PAUSED_ANOMALY
WAITING이상 이벤트 발생PAUSED_ANOMALY
NAVIGATING사용자 일시정지PAUSED_USER
WAITING사용자 일시정지PAUSED_USER
PAUSED_USER재개 요청NAVIGATING
PAUSED_ANOMALY이상 해제 및 재개 승인NAVIGATING
모든 순찰 상태배터리 부족RETURNING_HOME
모든 상태비상정지 발생EMERGENCY_STOP
RETURNING_HOME대기 위치 도착STOPPED 또는 COMPLETED
WAITING목표 순찰 횟수 완료COMPLETED
모든 순찰 상태중지 요청STOPPED

12. 클래스 설계

12.1 클래스명

class PatrolManager : public rclcpp::Node

12.2 주요 멤버 함수

함수명설명
declareParameters()ROS 2 파라미터 선언
loadParameters()파라미터 값 읽기
loadPatrolPoints()YAML 순찰 지점 파일 읽기
validatePatrolPoints()순찰 지점 데이터 검증
createInterfaces()토픽, 서비스, 액션 및 타이머 생성
handleStartRequest()순찰 시작 서비스 처리
handleStopRequest()순찰 중지 서비스 처리
handlePauseRequest()순찰 일시정지 서비스 처리
handleResumeRequest()순찰 재개 서비스 처리
validateStartConditions()순찰 시작 조건 검사
sendCurrentGoal()현재 순찰 지점을 Nav2 목표로 전송
sendGoal()지정 위치를 Nav2 목표로 전송
handleGoalResponse()Nav2 목표 수락 여부 처리
handleGoalFeedback()Nav2 이동 피드백 처리
handleGoalResult()Nav2 이동 결과 처리
handleNavigationSuccess()이동 성공 처리
handleNavigationFailure()이동 실패 처리
scheduleRetry()이동 재시도 예약
startPointWait()순찰 지점 대기 시작
handlePointWaitComplete()순찰 지점 대기 완료 처리
advanceToNextPoint()다음 순찰 지점으로 전환
completePatrolCycle()순찰 1회 완료 처리
checkPatrolCompletion()전체 순찰 완료 여부 확인
cancelCurrentGoal()현재 Nav2 목표 취소
requestReturnHome()대기 위치 복귀 요청
sendHomeGoal()대기 위치 Nav2 목표 전송
handleBatteryState()배터리 상태 저장
checkBatteryCondition()배터리 부족 여부 검사
handleAnomalyEvent()이상 이벤트 처리
handleEmergencyStop()비상정지 처리
publishStatus()현재 순찰 상태 발행
publishCurrentPoint()현재 순찰 지점 발행
publishEvent()순찰 이벤트 발행
publishLog()GUI용 로그 발행
changeState()순찰 상태 변경
publishZeroVelocity()비상정지용 정지 명령 발행

13. 초기화 처리

노드가 시작되면 다음 순서로 초기화한다.

  1. 노드명을 patrol_manager로 설정한다.
  2. ROS 2 파라미터를 선언한다.
  3. 파라미터 값을 읽는다.
  4. 순찰 지점 YAML 파일을 읽는다.
  5. 순찰 지점 데이터를 검증한다.
  6. 대기 위치 데이터를 검증한다.
  7. Nav2 액션 클라이언트를 생성한다.
  8. 서비스 서버를 생성한다.
  9. 입력 토픽 구독자를 생성한다.
  10. 상태 및 이벤트 발행자를 생성한다.
  11. 상태 발행 타이머를 생성한다.
  12. 배터리 검사 타이머를 생성한다.
  13. 내부 변수를 초기화한다.
  14. 현재 상태를 IDLE로 설정한다.
  15. 초기 상태 메시지를 발행한다.

순찰 지점 설정 파일을 읽을 수 없거나 필수 데이터가 누락된 경우 상태를 ERROR로 설정하고 순찰 시작 요청을 거부한다.

14. 순찰 시작 처리 절차

14.1 시작 요청 처리

  1. /patrol_manager/start 서비스 요청을 수신한다.
  2. 현재 상태가 시작 가능한 상태인지 확인한다.
  3. 상태를 VALIDATING으로 변경한다.
  4. 비상정지 상태를 확인한다.
  5. 현재 운용 모드를 확인한다.
  6. 배터리 잔량을 확인한다.
  7. 순찰 지점 목록을 확인한다.
  8. Nav2 액션 서버 연결 상태를 확인한다.
  9. AMCL 위치 추정 상태를 확인한다.
  10. 모든 조건이 정상이면 내부 변수를 초기화한다.
  11. current_index_를 0으로 설정한다.
  12. completed_cycles_를 0으로 설정한다.
  13. retry_count_를 0으로 설정한다.
  14. patrol_active_를 true로 설정한다.
  15. 순찰 시작 시각을 저장한다.
  16. PATROL_STARTED 이벤트를 발행한다.
  17. 첫 번째 순찰 지점을 Nav2 목표로 전송한다.
  18. 상태를 NAVIGATING으로 변경한다.

14.2 시작 조건 검사

다음 조건 중 하나라도 만족하지 않으면 순찰 시작을 거부한다.

emergency_stop_active_ == true
operation_mode_가 허용된 모드가 아님
battery_percentage_ < start_battery_threshold
patrol_points_.empty() == true
Nav2 액션 서버 연결 실패
현재 상태가 ERROR
현재 순찰이 이미 실행 중

15. 순찰 지점 이동 처리

15.1 현재 목표 선택

현재 목표는 다음과 같이 선택한다.

const PatrolPoint & target = patrol_points_.at(current_index_);

현재 지점 ID를 저장한다.

current_goal_id_ = target.id;

15.2 Nav2 목표 전송

  1. 현재 순찰 지점 데이터를 읽는다.
  2. PoseStamped 메시지를 생성한다.
  3. 좌표계는 순찰 지점의 frame_id를 사용한다.
  4. 기본 좌표계는 map으로 설정한다.
  5. x, y 좌표를 설정한다.
  6. yaw 값을 quaternion으로 변환한다.
  7. 목표 전송 시각을 저장한다.
  8. 목표 상태를 MOVING으로 발행한다.
  9. Nav2 액션 서버에 목표를 전송한다.
  10. 상태를 NAVIGATING으로 변경한다.

15.3 목표 수락 처리

Nav2가 목표를 수락한 경우 다음 작업을 수행한다.

goal_in_progress_ = true
last_nav_result_ = "ACCEPTED"

Nav2가 목표를 거부한 경우 이동 실패 처리 절차를 수행한다.

15.4 이동 피드백 처리

Nav2 피드백에서 다음 정보를 사용할 수 있다.

  • 현재 위치
  • 남은 거리
  • 예상 남은 시간
  • 복구 동작 횟수

원격 GUI 표시를 위해 다음 정보를 상태 메시지에 포함할 수 있다.

distance_remaining
estimated_time_remaining
number_of_recoveries

복구 동작 횟수가 비정상적으로 증가하면 경고 로그를 발행한다.

15.5 이동 성공 처리

Nav2 결과가 SUCCEEDED이면 다음 작업을 수행한다.

  1. goal_in_progress_를 false로 설정한다.
  2. retry_count_를 0으로 초기화한다.
  3. 도착 시각을 기록한다.
  4. 현재 지점 상태를 ARRIVED로 발행한다.
  5. GOAL_REACHED 이벤트를 발행한다.
  6. 현재 지점의 대기시간을 확인한다.
  7. 대기시간이 0보다 크면 상태를 WAITING으로 변경한다.
  8. 대기 타이머를 시작한다.
  9. 대기시간이 0이면 즉시 다음 지점으로 전환한다.

16. 순찰 지점 대기 처리

순찰 지점에 도착한 후 다음 절차를 수행한다.

  1. 로봇 이동을 정지 상태로 유지한다.
  2. 현재 지점 상태를 WAITING으로 발행한다.
  3. 지점별 wait_time_sec를 읽는다.
  4. 값이 없으면 default_wait_time_sec를 사용한다.
  5. 대기 타이머를 시작한다.
  6. 대기 중 이상 이벤트와 비상정지 입력을 계속 확인한다.
  7. 대기시간이 완료되면 다음 순찰 지점으로 전환한다.

대기 도중 이상 이벤트가 발생하면 대기 타이머의 남은 시간을 별도로 저장하지 않고, 순찰 재개 시 현재 지점 이동부터 다시 수행하는 것을 기본으로 한다.

17. 다음 순찰 지점 전환

다음 순찰 지점은 다음과 같이 결정한다.

current_index_++;

current_index_가 순찰 지점 개수보다 작은 경우 다음 지점으로 이동한다.

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

current_index_가 순찰 지점 개수 이상이면 순찰 1회를 완료한 것으로 처리한다.

if (current_index_ >= static_cast<int>(patrol_points_.size()))
{
  completePatrolCycle();
}

18. 순찰 횟수 관리

마지막 순찰 지점의 대기까지 완료하면 다음 작업을 수행한다.

  1. completed_cycles_를 1 증가시킨다.
  2. CYCLE_COMPLETED 이벤트를 발행한다.
  3. 목표 순찰 횟수를 확인한다.

patrol_repeat_count가 0이면 무한 반복한다.

if (patrol_repeat_count_ == 0)
{
  current_index_ = 0;
  sendCurrentGoal();
}

completed_cycles_가 설정된 반복 횟수보다 작은 경우 첫 번째 지점부터 다시 시작한다.

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

목표 반복 횟수에 도달한 경우 다음 작업을 수행한다.

  1. patrol_active_를 false로 설정한다.
  2. 상태를 COMPLETED로 변경한다.
  3. PATROL_COMPLETED 이벤트를 발행한다.
  4. return_home_on_complete가 true이면 대기 위치로 복귀한다.

Leave a Comment