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는 설정 파일에 정의된 순찰 지점을 순서대로 이동하고, 각 지점의 도착 여부와 대기시간을 관리한다.
주요 목적은 다음과 같다.
- 순찰 지점 목록을 설정 파일에서 불러온다.
- 순찰 시작 조건을 검사한다.
- 현재 순찰 지점을 Nav2 이동 목표로 전송한다.
- Nav2 이동 결과를 확인한다.
- 이동 성공 시 다음 순찰 지점으로 전환한다.
- 이동 실패 시 설정된 횟수만큼 재시도한다.
- 마지막 지점 완료 시 순찰 횟수를 증가시킨다.
- 지정된 반복 횟수만큼 순찰을 수행한다.
- 이상 이벤트 발생 시 이동을 일시정지한다.
- 배터리가 부족하면 순찰을 종료하고 대기 위치로 복귀한다.
- 비상정지 입력이 발생하면 현재 이동을 즉시 취소한다.
- 현재 상태를 원격 PC GUI에 전송한다.
5. 선행 조건
patrol_manager 실행 전 다음 조건이 충족되어야 한다.
- 터틀봇3 Bringup이 정상 실행되어야 한다.
- LiDAR 데이터가 정상 발행되어야 한다.
- 로봇의 오도메트리 데이터가 정상 발행되어야 한다.
- 지도 서버가 실행되어야 한다.
- AMCL 위치 추정이 완료되어야 한다.
- Nav2 서버가 활성화되어야 한다.
- 로봇의 초기 위치가 설정되어야 한다.
- 순찰 지점 설정 파일이 존재해야 한다.
- 터틀봇3와 원격 PC가 동일한 ROS 2 네트워크에 연결되어야 한다.
- 원격 PC와 터틀봇3의
ROS_DOMAIN_ID가 동일해야 한다.
6. 입력 인터페이스
6.1 입력 목록
| 구분 | 인터페이스명 | 자료형 | 설명 |
|---|---|---|---|
| 서비스 | /patrol_manager/start | std_srvs/srv/Trigger | 순찰 시작 요청 |
| 서비스 | /patrol_manager/stop | std_srvs/srv/Trigger | 순찰 중지 요청 |
| 서비스 | /patrol_manager/pause | std_srvs/srv/Trigger | 사용자 순찰 일시정지 요청 |
| 서비스 | /patrol_manager/resume | std_srvs/srv/Trigger | 순찰 재개 요청 |
| 토픽 | /operation_mode | std_msgs/msg/String | 현재 로봇 운용 모드 |
| 토픽 | /battery_state | sensor_msgs/msg/BatteryState | 배터리 잔량 및 전압 |
| 토픽 | /anomaly_event | turtlebot3_patrol_msgs/msg/AnomalyEvent | 이상 이벤트 |
| 토픽 | /emergency_stop | std_msgs/msg/Bool | 비상정지 상태 |
| 액션 결과 | /navigate_to_pose | nav2_msgs/action/NavigateToPose | Nav2 이동 결과 |
| TF | /tf, /tf_static | tf2_msgs/msg/TFMessage | 로봇 위치 및 좌표 변환 |
6.2 순찰 시작 서비스
서비스명은 다음과 같다.
/patrol_manager/start
서비스 형식은 다음과 같다.
std_srvs/srv/Trigger
순찰 시작 요청을 수신하면 다음 항목을 검사한다.
- 현재 상태가
IDLE,STOPPED또는COMPLETED인지 확인한다. - 비상정지 상태가 해제되어 있는지 확인한다.
- 운용 모드가 순찰 허용 모드인지 확인한다.
- 배터리가 순찰 시작 기준 이상인지 확인한다.
- Nav2 액션 서버가 사용 가능한지 확인한다.
- 순찰 지점이 1개 이상 등록되어 있는지 확인한다.
- AMCL 위치가 정상인지 확인한다.
모든 조건이 정상인 경우 서비스 응답은 다음과 같다.
success: true
message: "Patrol started"
조건이 만족되지 않는 경우 서비스 응답은 다음과 같다.
success: false
message: "Patrol start rejected: low battery"
6.3 순찰 중지 서비스
서비스명은 다음과 같다.
/patrol_manager/stop
순찰 중지 요청을 수신하면 다음 작업을 수행한다.
- 현재 Nav2 목표를 취소한다.
- 대기 타이머를 중지한다.
- 재시도 횟수를 초기화한다.
- 순찰 실행 상태를 해제한다.
- 상태를
STOPPED로 변경한다. - 중지 이벤트를 발행한다.
6.4 순찰 일시정지 서비스
서비스명은 다음과 같다.
/patrol_manager/pause
순찰 일시정지 요청을 수신하면 다음 작업을 수행한다.
- 현재 Nav2 목표를 취소한다.
- 현재 순찰 지점 번호를 유지한다.
- 순찰 횟수를 유지한다.
- 상태를
PAUSED_USER로 변경한다. - 일시정지 이벤트를 발행한다.
6.5 순찰 재개 서비스
서비스명은 다음과 같다.
/patrol_manager/resume
재개 요청을 수신하면 다음 조건을 검사한다.
- 현재 상태가
PAUSED_USER또는PAUSED_ANOMALY인지 확인한다. - 이상 이벤트가 해제되었는지 확인한다.
- 비상정지가 해제되었는지 확인한다.
- 배터리가 복귀 기준 이상인지 확인한다.
- 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이면 다음 작업을 즉시 수행한다.
- 현재 Nav2 목표를 취소한다.
- 순찰 타이머를 중지한다.
- 속도 명령이 계속 발생하지 않도록 상태를 변경한다.
- 상태를
EMERGENCY_STOP으로 변경한다. - 순찰 재개 요청을 거부한다.
- 비상정지 이벤트를 원격 GUI에 발행한다.
7. 출력 인터페이스
7.1 출력 목록
| 구분 | 인터페이스명 | 자료형 | 설명 |
|---|---|---|---|
| 액션 목표 | /navigate_to_pose | nav2_msgs/action/NavigateToPose | Nav2 이동 목표 |
| 토픽 | /patrol_manager/status | turtlebot3_patrol_msgs/msg/PatrolStatus | 현재 순찰 상태 |
| 토픽 | /patrol_manager/current_point | turtlebot3_patrol_msgs/msg/PatrolPointStatus | 현재 순찰 지점 |
| 토픽 | /patrol_manager/event | turtlebot3_patrol_msgs/msg/PatrolEvent | 순찰 이벤트 |
| 토픽 | /patrol_manager/log | std_msgs/msg/String | GUI 표시용 로그 |
| 토픽 | /return_home/request | std_msgs/msg/Bool | 대기 위치 복귀 요청 |
| 토픽 | /cmd_vel | geometry_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 순찰 지점 검증
설정 파일을 불러올 때 다음 항목을 검사한다.
patrol_points항목이 존재하는지 확인한다.- 순찰 지점이 1개 이상인지 확인한다.
- 각 지점에
id,x,y,yaw가 존재하는지 확인한다. - 순찰 지점 ID가 중복되지 않는지 확인한다.
wait_time_sec가 0 이상인지 확인한다.frame_id가 비어 있으면map을 기본값으로 사용한다.home_point가 존재하는지 확인한다.- 잘못된 값이 존재하면 노드 초기화를 실패 처리한다.
9. 내부 변수
| 변수명 | 자료형 | 초기값 | 설명 |
|---|---|---|---|
patrol_points_ | std::vector<PatrolPoint> | 빈 목록 | 전체 순찰 위치 목록 |
home_point_ | PatrolPoint | 기본값 | 대기 위치 |
current_index_ | int | 0 | 현재 순찰 위치 번호 |
completed_cycles_ | int | 0 | 완료한 순찰 횟수 |
retry_count_ | int | 0 | 현재 지점 이동 재시도 횟수 |
patrol_active_ | bool | false | 순찰 실행 상태 |
paused_by_anomaly_ | bool | false | 이상 이벤트에 의한 일시정지 |
paused_by_user_ | bool | false | 사용자 요청에 의한 일시정지 |
emergency_stop_active_ | bool | false | 비상정지 상태 |
low_battery_active_ | bool | false | 배터리 부족 상태 |
current_goal_id_ | std::string | 빈 문자열 | 현재 이동 목표 ID |
current_state_ | PatrolState | IDLE | 현재 상태 |
operation_mode_ | std::string | IDLE | 현재 운용 모드 |
battery_percentage_ | double | 100.0 | 현재 배터리 잔량 |
last_nav_result_ | std::string | 빈 문자열 | 마지막 Nav2 이동 결과 |
goal_in_progress_ | bool | false | Nav2 목표 수행 여부 |
waiting_at_point_ | bool | false | 순찰 지점 대기 상태 |
anomaly_event_id_ | std::string | 빈 문자열 | 현재 이상 이벤트 ID |
patrol_start_time_ | rclcpp::Time | 0 | 순찰 시작 시각 |
point_arrival_time_ | rclcpp::Time | 0 | 순찰 지점 도착 시각 |
last_status_publish_time_ | rclcpp::Time | 0 | 마지막 상태 발행 시각 |
nav_goal_handle_ | 액션 목표 핸들 | null | 현재 Nav2 목표 핸들 |
wait_timer_ | ROS 2 Timer | null | 순찰 지점 대기 타이머 |
status_timer_ | ROS 2 Timer | null | 상태 주기 발행 타이머 |
battery_check_timer_ | ROS 2 Timer | null | 배터리 상태 검사 타이머 |
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 | 정수 | 0 | 0이면 무한 반복 |
allowed_operation_mode | 문자열 배열 | PATROL, NIGHT_PATROL | 순찰 허용 모드 |
nav_action_name | 문자열 | /navigate_to_pose | Nav2 액션 서버명 |
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. 초기화 처리
노드가 시작되면 다음 순서로 초기화한다.
- 노드명을
patrol_manager로 설정한다. - ROS 2 파라미터를 선언한다.
- 파라미터 값을 읽는다.
- 순찰 지점 YAML 파일을 읽는다.
- 순찰 지점 데이터를 검증한다.
- 대기 위치 데이터를 검증한다.
- Nav2 액션 클라이언트를 생성한다.
- 서비스 서버를 생성한다.
- 입력 토픽 구독자를 생성한다.
- 상태 및 이벤트 발행자를 생성한다.
- 상태 발행 타이머를 생성한다.
- 배터리 검사 타이머를 생성한다.
- 내부 변수를 초기화한다.
- 현재 상태를
IDLE로 설정한다. - 초기 상태 메시지를 발행한다.
순찰 지점 설정 파일을 읽을 수 없거나 필수 데이터가 누락된 경우 상태를 ERROR로 설정하고 순찰 시작 요청을 거부한다.
14. 순찰 시작 처리 절차
14.1 시작 요청 처리
/patrol_manager/start서비스 요청을 수신한다.- 현재 상태가 시작 가능한 상태인지 확인한다.
- 상태를
VALIDATING으로 변경한다. - 비상정지 상태를 확인한다.
- 현재 운용 모드를 확인한다.
- 배터리 잔량을 확인한다.
- 순찰 지점 목록을 확인한다.
- Nav2 액션 서버 연결 상태를 확인한다.
- AMCL 위치 추정 상태를 확인한다.
- 모든 조건이 정상이면 내부 변수를 초기화한다.
current_index_를 0으로 설정한다.completed_cycles_를 0으로 설정한다.retry_count_를 0으로 설정한다.patrol_active_를true로 설정한다.- 순찰 시작 시각을 저장한다.
PATROL_STARTED이벤트를 발행한다.- 첫 번째 순찰 지점을 Nav2 목표로 전송한다.
- 상태를
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 목표 전송
- 현재 순찰 지점 데이터를 읽는다.
PoseStamped메시지를 생성한다.- 좌표계는 순찰 지점의
frame_id를 사용한다. - 기본 좌표계는
map으로 설정한다. x,y좌표를 설정한다.yaw값을 quaternion으로 변환한다.- 목표 전송 시각을 저장한다.
- 목표 상태를
MOVING으로 발행한다. - Nav2 액션 서버에 목표를 전송한다.
- 상태를
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이면 다음 작업을 수행한다.
goal_in_progress_를false로 설정한다.retry_count_를 0으로 초기화한다.- 도착 시각을 기록한다.
- 현재 지점 상태를
ARRIVED로 발행한다. GOAL_REACHED이벤트를 발행한다.- 현재 지점의 대기시간을 확인한다.
- 대기시간이 0보다 크면 상태를
WAITING으로 변경한다. - 대기 타이머를 시작한다.
- 대기시간이 0이면 즉시 다음 지점으로 전환한다.
16. 순찰 지점 대기 처리
순찰 지점에 도착한 후 다음 절차를 수행한다.
- 로봇 이동을 정지 상태로 유지한다.
- 현재 지점 상태를
WAITING으로 발행한다. - 지점별
wait_time_sec를 읽는다. - 값이 없으면
default_wait_time_sec를 사용한다. - 대기 타이머를 시작한다.
- 대기 중 이상 이벤트와 비상정지 입력을 계속 확인한다.
- 대기시간이 완료되면 다음 순찰 지점으로 전환한다.
대기 도중 이상 이벤트가 발생하면 대기 타이머의 남은 시간을 별도로 저장하지 않고, 순찰 재개 시 현재 지점 이동부터 다시 수행하는 것을 기본으로 한다.
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. 순찰 횟수 관리
마지막 순찰 지점의 대기까지 완료하면 다음 작업을 수행한다.
completed_cycles_를 1 증가시킨다.CYCLE_COMPLETED이벤트를 발행한다.- 목표 순찰 횟수를 확인한다.
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();
}
목표 반복 횟수에 도달한 경우 다음 작업을 수행한다.
patrol_active_를false로 설정한다.- 상태를
COMPLETED로 변경한다. PATROL_COMPLETED이벤트를 발행한다.return_home_on_complete가true이면 대기 위치로 복귀한다.