ROS 2 — 서비스와 액션 (토픽이 안 통할 때)
토픽 펍서브 모델로 안 되는 두 가지 — 짧은 질의응답과 긴 작업. 서비스와 액션이 그 자리를 채운다.
자율주행 로봇을 운영하면서 이런 명령들이 필요할 때가 있다.
- “지금 주행 모드 뭐야?” — 한 번 물어보고, 한 번 답받으면 끝
- “저 좌표(37.5, 127.0)까지 이동해” — 시간이 걸리고, 중간에 진행 상황도 알고 싶고, 도중에 취소도 할 수 있어야 함
이런 일들은 토픽으로 풀려고 하면 어색하다. 토픽은 라디오 방송 — 한쪽이 계속 흘려보내고 다른 쪽이 듣는 모델이라, 질문 → 답 이나 명령 → 진행 → 완료 같은 1대1 + 상태가 있는 흐름에는 안 맞는다.
그래서 ROS는 세 가지 통신 패턴을 갖는다.
| 패턴 | 비유 | 언제 쓰나 |
|---|---|---|
| 토픽 (Topic) | 라디오 방송 | 지속적인 데이터 흐름 — 카메라 영상, 센서값 |
| 서비스 (Service) | 전화 통화 | 짧은 질의응답 — “현재 모드 뭐야?”, “파라미터 X로 설정해줘” |
| 액션 (Action) | 택배 주문 | 시간 걸리는 명령 — “저 좌표로 이동해”, “물체 집어” (진행 상황·취소 지원) |
토픽은 이미 본 적 있을 거고, 이 글에서는 서비스 와 액션 을 본다.
1. 서비스 — 전화 통화
서비스는 요청(Request) → 응답(Response) 한 번이다. 함수를 호출하는 것과 비슷하다.
자율주행 로봇 예시로:
- 클라이언트 (요청하는 쪽): “현재 주행 모드 뭐야?”
- 서버 (응답하는 쪽): “주행 중” 이라고 답
- 끝
토픽처럼 계속 흐르는 게 아니라, 한 번 묻고 한 번 답하는 닫힌 거래다.
그림으로 보면
화살표 한 번, 응답 한 번. 끝. 토픽처럼 지속적으로 흐르는 게 아니라 닫힌 거래가 한 번 일어나고 종료된다.
서비스에는 두 가지가 붙는다.
- 이름 (예:
/get_status) — 토픽처럼 슬래시 경로 형식 - 타입 (예:
GetStatus) — 요청 형식 과 응답 형식 을 같이 정의 (.srv파일)
토픽이 이름 + 메시지 타입 1개 라면, 서비스는 이름 + (요청 타입 + 응답 타입) 이다.
2. 액션 — 택배 주문
서비스로는 짧은 질의응답은 잘 되지만, 시간이 걸리는 작업은 어색하다. “저 좌표까지 이동해” 같은 명령은 10초~수분이 걸릴 수 있고, 그동안:
- 진행 상황을 알고 싶다 (“지금 절반 왔어요”)
- 도중에 마음 바꾸면 취소할 수 있어야 한다
- 작업이 끝나면 최종 결과 를 받아야 한다
이게 액션 (Action) 패턴이다. 택배 주문 비유가 잘 맞는다:
- 주문 — “이 좌표로 이동해” → 액션 클라이언트 → 액션 서버 (접수)
- 진행 알림 — “지금 30% 왔어요” → 액션 서버 → 클라이언트 (배송 추적)
- 완료/실패 — “도착했어요” 또는 “장애물 때문에 실패” → 결과 전달
- 취소 — 도중에 “취소할게요” 가능
그림으로 보면
서비스의 한 번 요청 → 한 번 응답 과 다르게, 한 번 목표 → 여러 번 진행 알림 → 한 번 최종 결과 의 흐름이다. 도중에 클라이언트가 취소 도 가능.
그래서 액션에는 세 가지 타입이 한 묶음으로 들어간다 — Goal(목표), Feedback(진행), Result(최종). 이 셋이 .action 파일에 같이 정의된다.
참고 — 액션 안에는 사실 서비스 + 토픽 여러 개가 조합돼 있다. 목표 전송은 서비스, 진행 알림은 토픽, 결과는 서비스. ROS 2가 그걸 한 묶음으로 추상화한 것.
3. 세 패턴 한눈에 비교
| 토픽 | 서비스 | 액션 | |
|---|---|---|---|
| 비유 | 라디오 방송 | 전화 통화 | 택배 주문 |
| 방향 | 일방적 (구독자 여러 명) | 양방향 1회 (요청-응답) | 양방향 + 진행 알림 + 취소 |
| 응답 받는가? | X | O (한 번) | O (진행 + 최종) |
| 시간 걸리는가? | 보통 짧음 (각 메시지) | 짧음 (즉시 답) | 길어도 됨 |
| 이름 예시 | /camera/image | /get_status | /navigate_to_pose |
| 타입 파일 | .msg (메시지 1개) | .srv (Request + Response) | .action (Goal + Feedback + Result) |
4. 자율주행 로봇에서는?
자율주행 로봇 시스템에는 세 패턴이 다 섞여서 쓰인다.
- 토픽 — 카메라 영상 / 라이다 / GPS / 모터 속도 명령 (지속적 데이터 흐름)
- 서비스 — “현재 주행 모드는?”, “비상정지 해제해줘”, “PID gain 바꿔줘” (짧은 질의·설정)
- 액션 — “저 좌표까지 이동해” (Nav2의
NavigateToPose), “지정 경로 따라가” (이동·매니퓰레이션 류)
대부분의 ROS 시스템은 “센서 토픽을 받아서 알고리즘이 액션 서버를 호출하고, 사용자한테는 서비스로 상태를 노출” 같은 식으로 세 패턴을 조합해서 굴러간다.
5. 직접 보기 — ros2 service / ros2 action 명령
토픽처럼 서비스·액션도 자기 명령어가 있다.
$ ros2 service list
/get_status
/set_parameters
/emergency_stop
$ ros2 service type /get_status
my_robot_interfaces/srv/GetStatus
$ ros2 service call /get_status my_robot_interfaces/srv/GetStatus
# 한 번 호출하고 응답을 출력함
$ ros2 action list
/navigate_to_pose
/follow_path
$ ros2 action send_goal /navigate_to_pose nav2_msgs/action/NavigateToPose \
"{pose: {position: {x: 37.5, y: 127.0}}}"
# 진행 상황(feedback)을 한 줄씩 출력하다가, 끝나면 result 출력
한 줄로 박아둘 것
- 토픽이 안 통하는 경우 두 가지 — 짧은 질의응답(서비스) 과 시간 걸리는 명령(액션)
- 서비스 = 전화 통화 — 한 번 묻고 한 번 답. 이름 + (요청 타입 + 응답 타입)
- 액션 = 택배 주문 — 시간 걸리는 작업 + 진행 알림 + 취소 + 최종 결과. 이름 + (Goal + Feedback + Result)
- 세 패턴은 같은 노드 위에서 같이 동작 — 한 노드가 토픽도 발행하고 서비스도 제공하고 액션 서버도 띄울 수 있다
- 액션 안에는 서비스 + 토픽이 조합돼 있다 — ROS 2가 그걸 한 묶음으로 추상화