[ROS 2로 시작하는 로봇 프로그래밍]에 기반한 정리글입니다.
토픽
은 비동기식 단방향 메시지 송수신 방식
으로, msg 인터페이스 형태의 메시지를 보내는 Publisher와 메시지를 받는 Subscriber 간의 통신이다.
이는 1:1 통신을 기본으로 하지만 N:N 통신도 가능하며, ROS 메시지 통신에서 가장 많이 사용된다.
비동기성
과 연속성
을 가지기 때문에 센서 값 전송이나 항시 정보를 주고받아야 하는 부분에서 주로 사용된다.
이전 포스팅의 turtlesim 노드를 이용하여 토픽을 알아본다. turtlesim 노드를 실행한 후 $ ros2 node info /turtlesim
명령어를 확인하여 해당 노드의 토픽 정보를 확인한다.
$ ros2 run turtlesim turtlesim_node
$ ros2 node info /turtlesim
여기서, geometry_msgs/msg/Twist
형태의 cmd_vel
과, turtlesim/msg/Color
형태의 Color_sensor
등을 Subscribe하고 Publish함을 알 수 있다.
아래 명령어로 현재 개발환경에서 동작 중인 모든 노드들의 토픽 정보를 확인할 수 있다.
-t 옵션은 각 메시지의 type를 보여주는 옵션이다.
$ ros2 topic list -t
turtle_teleop_key 노드를 실행시킨 후, 아래 명령어로 토픽의 메시지 형태, Publisher, Subscriber 정보를 확인할 수 있다.
$ ros2 run turtlesim turtle_teleop_key
$ ros2 topic info /turtle1/cmd_vel
특정 토픽의 메시지 내용을 실시간으로 표시할 수 있다. teleop_turtle 노드를 실행한 터미널 창에서 방향키로 명령을 내리면 토픽 값을 확인할 수 있다.
$ ros2 topic info /turtle1/cmd_vel
토픽의 대역폭, 주기, 지연시간도 아래의 명령어로 확인 가능하다.
$ ros2 topic bw /turtle1/cmd_vel
$ ros2 topic hz /turtle1/cmd_vel
$ ros2 topic delay /TOPIC_NAME
토픽 Publish는 ROS 프로그램에 내장하는 것이 기본이나, 여기서는 ros2 topic pub
명령어를 통해 토픽을 Publish 해본다. 명령어의 사용법은 다음과 같다.
$ ros2 topic pub <topic_name> <msg_type> "<args>"
예로, 병진 속도를 linear x 값으로 2.0m/s, 회전 속도를 1.8rad/s로 입력하여 토픽을 Publish하는 명령어이다.
$ ros2 topic pub --once /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 1.8}}"
지속적으로 Publish하기를 원한다면, --once
옵션 대신 --rate 1
옵션을 통해 1Hz 주기로 Publish할 수 있다.
ROS 2에는 rosbag
이라는 기능이 있는데, 이는 Publish되는 토픽을 파일 형태로 저장하고, 필요할 대 저장된 토픽을 다시 불러와 동일한 주기로 재생할 수 있는 기능이다.
이 기능은 알고리즘의 입력 값을 고정하고 반복 테스트하여 알고리즘 개선 작업 및 성능 검증 테스트를 하는 데 큰 도움이 된다.
아래 명령어로 토픽을 저장할 수 있다. ctrl+c
로 저장을 끝낼 수 있다.
$ ros2 bag record /turtle1/cmd_vel
저장이 끝나면 토픽을 저장한 폴더가 생성되며, 아래 명령어로 저장된 토픽을 재생할 수 있다.
$ ros2 bag play rosbag2_2023_01_02-02_10_39/
아래 명령어로 rosbag 파일의 정보를 확인할 수 있다.
$ ros2 bag info rosbag2_2023_01_02-02_10_39/
서비스는 동기식 양방향 메시지 송수신 방식으로, 서비스 요청(Request) 하는 쪽을 Server Client
, 요청받은 서비스를 수행한 후 서비스 응답(Response)을 하는 쪽을 Service Server
라고 한다. 즉, 서비스는 특정 요청을 하는 클라이언트 단과 요청받은 일을 수행한 후에 결과값을 전달하는 서버 단과의 통신이다. 인터페이스는 srv
를 사용한다.
서비스는 동일한 서비스 서버에 대해 복수의 클라이언트를 가질 수 있도록 설계되었지만, 서비스 응답은 서비스 요청이 있었던 서비스 클라이언트에 대해서만 응답하는 형태이다.
이전과 마찬가지로 turtlesim 패키지를 이용한다. 먼저 turtlesim 노드를 실행하고, 서비스 목록을 확인하는 명령어를 실행한다. -t
옵션은 서비스 형태 확인 옵션이다.
$ ros2 run turtlesim turtlesim_node
$ ros2 service list -t
특정 서비스의 형태가 궁금할땐 ros2 service type
명령어를 사용할 수 있다.
$ ros2 service type
서비스 형태 확인에서 특정 형태를 입력하면 해당 형태의 서비스를 사용하는 서비스명을 확인할 수 있다.
서비스 서버에게 서비스 요청(Request)을 하는 명령어는 $ ros2 service call <service_name> <service_type> "<arguments>"
로 할 수 있다.
먼저 turtlesim_teleop_key 노드를 실행하고 방향키로 이리저리 거북이를 움직여본다.
이후 명령어로 /clear
서비스를 요청하면, 이동 궤적이 모두 지워짐을 알 수 있다.
또한 /kill
서비스를 요청하면 거북이가 사라짐을 알 수 있다.
/reset
서비스를 요청하면 모두 리셋되며 새로운 거북이가 등장한다.
$ ros2 run turtlesim turtle_teleop_key
$ ros2 service call /clear std_srvs/srv/Empty
$ ros2 service call /kill turtlesim/srv/Kill "name: 'turtle1'"
$ ros2 service call /reset std_srvs/srv/Empty
액션은 비동기식, 동기식 양뱡향 메시지 송수신 방식
으로, 액션 목표를 지정하는 Action Client
와, 액션 목표(Goal)
를 받아 특정 태스크를 수행하면서 중간 결과값을 전송하는 액션 피드백(Feedback)
, 최종 결과값을 담은 액션 결과(Result)
를 전송하는 Action Server
간의 통신이다.
ROS 2에서의 액션은 목표 전달(send_goal)
, 표 취소(cancel_goal)
,결과 받기(get_result)
를 위한 서비스 통신을 사용하기 위하여 토픽과 서비스 방식을 혼합하여 사용한다. 비동기 방식에서 원하는 타이밍에 적절한 액션을 수행하기 위하여 목표상태(goal_state)
를 도입하였고, 이는 목표값을 전달한 후 상태 머신을 구동하여 액션의 프로세스를 쫒는다.
즉, 액션 목표 전달 이후 액션의 상태값을 액션 클라이언트에 전달함에 따라, 비동기 및 동기 방식이 혼재된 액션의 처리를 원할하게 해준다.
(출처 : https://design.ros2.org/articles/actions.html)
turtlesim 노드와, teleop_key 노드로 액션을 실습한다.
$ ros2 run turtlesim turtlesim_node
$ ros2 run turtlesim turtle_teleop_key
여기서, G B V C D E R T 키를 통하여 거북이를 회전시킬 수 있는데, 이는 모두 지정된 절대 각도로 거북이가 회전하는 지정키이다. 만약 F 키를 누른다면 전달한 목표값을 취소하여 동작을 멈추게 한다.
실행된 노드의 액션 정보를 확인하기 위하여 ros2 node info
를 사용한다.
$ ros2 node info /turtlesim
액션 목록 명령어를 이용하여 현재 실행 중인 액션 목록을 확인할 수 있다.
$ ros2 action list -t
액션 목록을 더 자세히 확인하려면 액션 정보 명령어를 사용한다.
$ ros2 action info /turtle1/rotate_absolute
명령어를 사용하여 액션 목표를 전달할 수 있다. 명령어의 형태는 다음과 같다.
$ ros2 action send_goal <action_name> <action_type> "<values>"
예를 들어 거북이에게 theta: 1.5708
라는 목표값을 주면, 아래와 같이 이동하며, 전달한 목표값과 액션 목표의 UID를 표시한다. 통신이 끝나면 이동 시작 자세로부터 변위 값인 delta
를 표시한다.
명령어의 끝에 --feedback
을 붙인다면 남은 회전량을 피드백으로 계속 표시해준다.
이번 포스팅에서는 노드 간 메시지 통신 방식인 토픽, 서비스, 액션을 정리하였다. 각 통신 방식의 개념과 인터페이스, 사용방법 등을 알게 되었고 turtlesim 패키지의 예제를 통하여 어떻게 사용되는지 구체적으로 알 수 있었다.
다음 포스팅은 ROS 2의 인터페이스, 파라미터에 대하여 정리한다.
멋져요~~