이번 실습에서는 ROS 2 Python 패키지를 구성하고, Topic, Service, Action을 하나의 패키지에서 연동하는 실습을 진행했다.
argument, operator, calculator, checker 노드를 실행하여 각각의 통신이 실제로 동작하는 것을 확인했다.
실습에 사용한 패키지는 다음과 같다.
topic_service_action_rclpy_example
패키지에는 총 4개의 노드가 구성되어 있다.
전체적인 구조는 다음과 같다.
argument
│
│ Topic
▼
calculator ◀──── Service ──── operator
▲
│
│ Action
│
checker
먼저 package.xml을 수정했다.
nano ~/robot_ws/src/ros2-seminar-examples/topic_service_action_rclpy_example/package.xml
주요 의존성은 다음과 같다.
<depend>rclpy</depend>
<depend>std_msgs</depend>
<depend>msg_srv_action_interface_example</depend>
그리고 Python 패키지이기 때문에 다음과 같이 설정했다.
<build_type>ament_python</build_type>
다음으로 Python 패키지 설정 파일인 setup.py를 확인했다.
nano ~/robot_ws/src/ros2-seminar-examples/topic_service_action_rclpy_example/setup.py
각 노드를 ros2 run으로 실행할 수 있도록 console_scripts에 등록되어 있다.
entry_points={
'console_scripts': [
'argument = topic_service_action_rclpy_example.arithmetic.argument:main',
'operator = topic_service_action_rclpy_example.arithmetic.operator:main',
'calculator = topic_service_action_rclpy_example.calculator.main:main',
'checker = topic_service_action_rclpy_example.checker.main:main',
],
},
이를 통해 다음과 같이 노드를 실행할 수 있다.
ros2 run topic_service_action_rclpy_example argument
ros2 run topic_service_action_rclpy_example operator
ros2 run topic_service_action_rclpy_example calculator
ros2 run topic_service_action_rclpy_example checker
워크스페이스로 이동한 후 패키지를 빌드했다.
cd ~/robot_ws
colcon build --symlink-install --packages-select topic_service_action_rclpy_example
빌드가 정상적으로 완료되는 것을 확인했다.
실습 자료에서는 다음과 같은 alias도 사용한다.
cw
cbp topic_service_action_rclpy_example
하지만 현재 환경에는 해당 alias가 설정되어 있지 않아 실제 명령어를 사용했다.
cd ~/robot_ws
colcon build --symlink-install --packages-select topic_service_action_rclpy_example
먼저 calculator 노드를 실행했다.
source ~/robot_ws/install/setup.zsh
ros2 run topic_service_action_rclpy_example calculator
calculator는 다른 노드의 Topic, Service, Action 요청을 처리하는 중심 역할을 한다.
새 터미널에서 argument 노드를 실행했다.
source ~/robot_ws/install/setup.zsh
ros2 run topic_service_action_rclpy_example argument
실행하면 a, b 값이 계속 발행된다.
[INFO] [argument]: Published argument a: 6.0
[INFO] [argument]: Published argument b: 8.0
calculator에서는 해당 값을 구독한다.
[INFO] [calculator]: Subscribed argument a: 6.0
[INFO] [calculator]: Subscribed argument b: 8.0
따라서 argument와 calculator 사이의 Topic 통신이 정상적으로 이루어지는 것을 확인했다.
다음으로 operator 노드를 실행했다.
source ~/robot_ws/install/setup.zsh
ros2 run topic_service_action_rclpy_example operator
operator는 +, -, *, / 중 하나의 연산을 선택하여 calculator에게 Service 요청을 보낸다.
예를 들어 다음과 같은 결과가 출력되었다.
[operator]: Result: 3.0
[operator]: Result: 8.0
[operator]: Result: 0.5
[operator]: Result: 12.0
calculator에서도 실제 계산 결과가 출력되는 것을 확인했다.
[calculator]: 4.0 * 0.0 = 0.0
[calculator]: 2.0 / 8.0 = 0.25
이를 통해 Service Client인 operator와 Service Server인 calculator의 통신이 정상적으로 동작하는 것을 확인했다.
마지막으로 checker 노드를 실행했다.
source ~/robot_ws/install/setup.zsh
ros2 run topic_service_action_rclpy_example checker
실행하면 Action Goal이 전달되고 Feedback이 계속 출력된다.
[checker]: Action goal accepted.
[checker]: Action feedback: [...]
checker는 계산 결과를 계속 누적하고, 목표 합계에 도달하면 Action이 종료된다.
이번 실습에서는 최종적으로 다음 결과가 출력되었다.
[checker]: Action result(total sum): 51.75
기본 목표값인 50을 넘어 51.75가 되면서 Action이 성공적으로 종료되었다.

이번 실습에서 확인한 ROS 2 통신 구조는 다음과 같다.
argument
│
│ Topic
▼
calculator
▲ ▲
│ │
Service Action
│ │
operator checker
각 노드의 역할을 정리하면 다음과 같다.
| 노드 | 역할 |
|---|---|
argument | Topic Publisher |
calculator | Topic Subscriber / Service Server / Action Server |
operator | Service Client |
checker | Action Client |
이번 실습에서는 ROS 2 Python 패키지의 설정부터 빌드, 실행까지 진행하고 Topic → Service → Action으로 이어지는 노드 간 통신 구조를 직접 확인했다.
특히 calculator가 여러 통신 방식을 동시에 처리하는 중심 노드로 동작하는 과정을 확인하면서 ROS 2 패키지의 전체적인 구조를 이해할 수 있었다.