이번 시간에는 ROS 2의 핵심인 3가지 통신 메커니즘(Topic,Service, Action)에 대해서 개념을 다잡고 넘어가고자 합니다. 프로그래밍은 없지만, 각각의 통신 메커니즘들에 대해 반드시 숙지하고 넘어가시기 바랍니다!
⇒ 위 그림에서 동그라미는 Node를 뜻하고, 화살표는 topic을 뜻하는데요, 첫번째로 이 Topic이라는 것이 무엇인지 배워보고자 합니다.
image from : docs.ros.org
image from : docs.ros.org
image from : ethz.ch
ROS 1 | geometry_msgs/Twist |
---|---|
ROS 2 | geometry_msgs/msg/Twist |
ROS에서는 topic에 대한 정보, 파싱, 송수신과 같은 여러 인터페이싱이 가능하도록 CLI를 제공하고 있습니다. topic과 msg에 대한 CLI들을 살펴봅시다!
# Terminal 1
$ ros2 topic pub /chatter std_msgs/String "data: Hello ROS Developers"
# Terminal 2
$ ros2 topic echo /chatter
$ ros2 topic list
/topic_a
/topic_b
...
/clock
/parameter_events
/performance_metrics
/rosout
$ ros2 topic info /chatter
Type: std_msgs/msg/String
Publisher count: 1
Subscription count: 1
⇒ verbose option을 통해 더욱 자세한 내용을 알 수 있지만 지금은 넘어가겠습니다.
$ ros2 topic info /chatter --verbose
Type: std_msgs/msg/String
Publisher count: 1
Node name: _ros2cli_84037
Node namespace: /
Topic type: std_msgs/msg/String
Endpoint type: PUBLISHER
GID: 30.06.10.01.46.68.e4.44.22.bd.f2.21.00.00.08.03.00.00.00.00.00.00.00.00
QoS profile:
Reliability: RMW_QOS_POLICY_RELIABILITY_RELIABLE
Durability: RMW_QOS_POLICY_DURABILITY_VOLATILE
Lifespan: 9223372036854775807 nanoseconds
Deadline: 9223372036854775807 nanoseconds
Liveliness: RMW_QOS_POLICY_LIVELINESS_AUTOMATIC
Liveliness lease duration: 9223372036854775807 nanoseconds
Subscription count: 1
Node name: _ros2cli_84065
Node namespace: /
Topic type: std_msgs/msg/String
Endpoint type: SUBSCRIPTION
GID: 48.95.10.01.ea.a0.fa.d5.31.c6.85.40.00.00.08.04.00.00.00.00.00.00.00.00
QoS profile:
Reliability: RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT
Durability: RMW_QOS_POLICY_DURABILITY_VOLATILE
Lifespan: 9223372036854775807 nanoseconds
Deadline: 9223372036854775807 nanoseconds
Liveliness: RMW_QOS_POLICY_LIVELINESS_AUTOMATIC
Liveliness lease duration: 9223372036854775807 nanoseconds
$ ros2 topic type /chatter
std_msgs/msg/String
$ ros2 interface show std_msgs/msg/String
# This was originally provided as an example message.
# It is deprecated as of Foxy
# It is recommended to create your own semantically meaningful message.
# However if you would like to continue using this please use the equivalent in example_msgs.
string data
$ ros2 topic echo /chatter
...
data: Hello ROS Developers
---
data: Hello ROS Developers
---
$ ros2 topic hz /chatter
average rate: 1.000
min: 1.000s max: 1.000s std dev: 0.00013s window: 3
average rate: 1.000
min: 1.000s max: 1.000s std dev: 0.00017s window: 5
...
$ ros2 topic pub /chatter std_msgs/String "data: Hello ROS Developers"
...
publishing #1: std_msgs.msg.String(data='Hello ROS Developers')
publishing #2: std_msgs.msg.String(data='Hello ROS Developers')
publishing #3: std_msgs.msg.String(data='Hello ROS Developers')
CMD | Description |
---|---|
ros2 topic list | 전체 topic 조회 |
ros2 topic info | 특정 topic 정보 조회 |
ros2 topic type | 특정 topic type 조회 |
ros2 interface show | msg type 조회 |
ros2 topic echo | topic 엿보기 |
ros2 topic hz | topic pub/sub 주기 조회 |
ros2 topic pub | 간단한 publish |
Topic에 이어 ROS의 통신 메커니즘 두번째로 Service를 배워보겠습니다.
image from : docs.ros.org
image from : https://docs.ros.org/en/foxy/Tutorials/Services/Understanding-ROS2-Services.html
Service의 중요한 특징 ⇒ 하나의 Service Server에 여러 Client가 request 할 수 있지만, Server는 동시에 여러 request를 처리하지 못합니다.
image from : docs.ros.org
마지막으로, Topic과 비교하여 Service의 특징을 알아봅시다.
Service는 Topic과는 다르게 일회성이기 때문에 CLI를 사용할 일이 매우 잦습니다. 자주 사용되는 만큼 얼른 학습해봅시다!
ros2 launch husky_gazebo husky_playpen.launch.py
$ ros2 service list
/controller_manager/configure_and_start_controller
/controller_manager/configure_controller
/controller_manager/describe_parameters
...
$ ros2 service type /controller_manager/configure_and_start_controller
controller_manager_msgs/srv/ConfigureStartController
$ ros2 interface show controller_manager_msgs/srv/ConfigureStartController
# The ConfigureStartController service allows you to configure and start a single controller
# inside controller_manager
# To configure and start a controller, specify the "name" of the controller.
# The return value "ok" indicates if the controller was successfully
# configured and started or not.
string name
---
bool ok
서비스 타입 중간에 보이는 - - - 부분은 request와 response의 구분자라고 생각하시면 됩니다.
$ ros2 service call /get_model_list gazebo_msgs/srv/GetModelList {}
requester: making request: gazebo_msgs.srv.GetModelList_Request()
response:
gazebo_msgs.srv.GetModelList_Response(header=std_msgs.msg.Header(stamp=builtin_interfaces.msg.Time(sec=1594, nanosec=330000000), frame_id=''), model_names=['ground_plane', 'jersey_barrier', 'jersey_barrier_0', 'jersey_barrier_1', 'jersey_barrier_2', 'jersey_barrier_3', 'jersey_barrier_4', 'jersey_barrier_5', 'jersey_barrier_6', 'jersey_barrier_7', 'jersey_barrier_8', 'jersey_barrier_9', 'jersey_barrier_10', 'jersey_barrier_11', 'jersey_barrier_12', 'jersey_barrier_13', 'jersey_barrier_14', 'fire_hydrant', 'fire_hydrant_0', 'fire_hydrant_1', 'Dumpster', 'Dumpster_0', 'jersey_barrier_15', 'Construction Cone', 'Construction Barrel', 'Construction Cone_0', 'Construction Barrel_0', 'asphalt_plane', 'Construction Barrel_1', 'Construction Barrel_2', 'Construction Barrel_3', 'Construction Barrel_4', 'Construction Barrel_5', 'Construction Barrel_6', 'Construction Barrel_7', 'Construction Cone_1', 'husky'], success=True)
⇒ Gazebo 상에 존재하는 모델들의 리스트를 response로 받았습니다. (gazebo ros에서 이러한 기능들이 제공됩니다.)
CMD | Description |
---|---|
ros2 service list | 전체 Service 리스트 |
ros2 service type | 특정 Service가 사용하는 데이터 타입 조회 |
ros2 interface show | 특정 srv에 대한 자세한 정보 조회 |
ros2 service call | 터미널을 통해 Service Call |
ROS 2의 마지막 통신 메커니즘인 Action을 배워보겠습니다.
Action은 바로 이러한 Service의 단점을 극복하기 위해 탄생한 통신 메커니즘입니다. Action은 Service와 Topic의 특성을 모두 갖고 있으며, 실제로 가장 늦게 탄생한 통신 메커니즘입니다.
Action의 특징
⇒ 하지만, 여러 request를 동시에 작업하는 것이나, Feedback 중에 topic subscribe와 같은 작업은 본질적으로 불가합니다. 이에 대한 해결 방법도 후에 살펴보겠습니다.
사진과 같이 Action Client와 Server가 주고받는 내용은 크게 5가지가 있습니다.
만약 4번 도중 cancel이 발생하면 Action은 종료됩니다.
이렇게 Action은 Topic, Service의 특징을 모두 갖고 있으며 Feedback 결과에 따라 Cancel이라는 추가 기능까지 갖추고 있는 복잡한 통신 메커니즘입니다.
sudo apt install ros-foxy-turtlesim -y
ros2 run turtlesim turtlesim_node
$ ros2 action list
/turtle1/rotate_absolute
$ ros2 action info /turtle1/rotate_absolute
Action: /turtle1/rotate_absolute
Action clients: 0
Action servers: 1
/turtlesim
$ ros2 interface show turtlesim/action/RotateAbsolute
# The desired heading in radians
float32 theta
---
# The angular displacement in radians to the starting position
float32 delta
---
# The remaining rotation in radians
float32 remaining
$ ros2 action send_goal <action_name> <action_type> <values>
$ ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta : 0.0}" --feedback
1657646954.088327 [0] ros2: using network interface enp7s0 (udp/166.104.135.89) selected arbitrarily from: enp7s0, docker0
Waiting for an action server to become available...
Sending goal:
theta: 0.0
Goal accepted with ID: d3ddca85948d4099a13dbeb8183e5ecc
Result:
delta: -0.7839995622634888
Goal finished with status: SUCCEEDED
/turtle1/rotate_absolute는 거북이를 특정한 절대 각도로 회전시키는 action으로 feedback 옵션 지정 시 커멘드 라인 상에 변화하는 각도록 실시간으로 확인 가능합니다.
CMD | Description |
---|---|
ros2 action list | 전체 action list 조회 |
ros2 action info | 특정 action 정보 조회 |
ros2 interface show | 특정 action 데이터 타입에 대한 조회 |
ros2 action send_goal | 터미널을 통한 action goal request |
여기까지 배웠다면 ROS 2의 개념적인 부분은 대부분 습득하셨다고 보아도 좋습니다. 그럼 앞으로 프로그래밍과 예시들을 통해 ROS 2 시스템에 더욱 능숙해져보겠습니다.