서비스는 ROS 그래프의 노드가 통신하는 방법 중 하나이다. 토픽에서 퍼블리셔와 서브스크라이버처럼, 서비스에는 요청(Request)와 응답(Response)이 있다. 노드는 토픽을 통해 데이터를 지속적으로 받을 수 있지만, 서비스는 요청한 경우에만 데이터를 받는다.
이전처럼 turtlesim
을 열자.
ros2 run turtlesim turtlesim_node
ros2 run turtlesim turtle_teleop_key
ros2 service list
ros2 service list
명령어를 통해 현재 활성화된 서비스들을 볼 수 있다.
ros2 service list
/clear
/kill
/reset
/spawn
/teleop_turtle/describe_parameters
/teleop_turtle/get_parameter_types
/teleop_turtle/get_parameters
/teleop_turtle/list_parameters
/teleop_turtle/set_parameters
/teleop_turtle/set_parameters_atomically
/turtle1/set_pen
/turtle1/teleport_absolute
/turtle1/teleport_relative
/turtlesim/describe_parameters
/turtlesim/get_parameter_types
/turtlesim/get_parameters
/turtlesim/list_parameters
/turtlesim/set_parameters
/turtlesim/set_parameters_atomically
/teleop_turtle
, turtle1
모두 parameter
를 포함하는 6개의 서비스를 보유하고 있다.
이는 ROS 2의 대부분이 그러한데, parameter
가 구축된 인프라 서비스가 존재한다.
그 외에도 이전에 rqt
에서 보았던 /clear
, /spawn
, /set_pen
이 보인다.
ros2 service type
서비스는 요청과 응답을 할 데이터의 구조를 알려주는 타입을 가지고 있다.
토픽의 타입처럼 서비스 또한 비슷하게 정의되는데, 요청과 응답에 대한 메시지가 개별적으로 존재한다.
서비스의 타입을 알아보기 위해, 다음의 명령어를 수행한다.
ros2 service type <service_name>
서비스 /clear
로 한 번 해보자.
ros2 service type /clear
std_srvs/srv/Empty
Empty
는 어떠한 데이터도 송신/수신하지 않는다는 의미이다.
ros2 service list -t
옵션--show-types
또는 -t
를 추가하여 서비스의 타입까지 한번에 볼 수 있다.
ros2 service list -t
/clear [std_srvs/srv/Empty]
/kill [turtlesim/srv/Kill]
/reset [std_srvs/srv/Empty]
/spawn [turtlesim/srv/Spawn]
/teleop_turtle/describe_parameters [rcl_interfaces/srv/DescribeParameters]
/teleop_turtle/get_parameter_types [rcl_interfaces/srv/GetParameterTypes]
/teleop_turtle/get_parameters [rcl_interfaces/srv/GetParameters]
/teleop_turtle/list_parameters [rcl_interfaces/srv/ListParameters]
/teleop_turtle/set_parameters [rcl_interfaces/srv/SetParameters]
/teleop_turtle/set_parameters_atomically [rcl_interfaces/srv/SetParametersAtomically]
/turtle1/set_pen [turtlesim/srv/SetPen]
/turtle1/teleport_absolute [turtlesim/srv/TeleportAbsolute]
/turtle1/teleport_relative [turtlesim/srv/TeleportRelative]
/turtlesim/describe_parameters [rcl_interfaces/srv/DescribeParameters]
/turtlesim/get_parameter_types [rcl_interfaces/srv/GetParameterTypes]
/turtlesim/get_parameters [rcl_interfaces/srv/GetParameters]
/turtlesim/list_parameters [rcl_interfaces/srv/ListParameters]
/turtlesim/set_parameters [rcl_interfaces/srv/SetParameters]
/turtlesim/set_parameters_atomically [rcl_interfaces/srv/SetParametersAtomically]
ros2 service find
특정 타입을 가지는 서비스를 찾을 때 사용한다.
ros2 service find <type_name>
ros2 service find std_srvs/srv/Empty
/clear
/reset
ros2 interface show
서비스를 호출하기 위해서는 먼저 입력 인자에 대해 알고 있어야 한다.
ros2 interface show <type_name>.srv
ros2 interface show std_srvs/srv/Empty.srv
---
구분선 ---
을 기준으로 위쪽이 요청 메시지의 구조이고, 아래쪽이 응답 메시지의 구조이다.
Empty
는 별다른 메시지의 구조가 없기에, 구분선만 출력된다.
서비스 /spawn
의 구조를 알아보자. 타입은 ros2 service list -t
로 turtlesim/srv/Spawn
임을 알 수 있다.
ros2 interface show turtlesim/srv/Spawn.srv
float32 x
float32 y
float32 theta
string name # Optional. A unique name will be created and returned if this is empty
---
string name
이를 통해 해당 서비스의 호출을 위해서는 최대 x
, y
, theta
, name
변수가 필요함을 알 수 있다.
ros2 service call
이제 서비스를 호출할 일만 남았다.
다음 명령어로 서비스를 호출해 보자.
ros2 service call <service_name> <service_type> <arguments>
Empty
처럼 인자가 없는 경우에는 <arguments>
를 비워두면 된다.
ros2 service call /clear std_srvs/srv/Empty
waiting for service to become available...
requester: making request: std_srvs.srv.Empty_Request()
response:
std_srvs.srv.Empty_Response()
이번엔 /spawn
서비스를 호출하여 새 거북이를 생성해 보자.
<argument>
는 YAML형식을 따름에 주의하자.
ros2 service call /spawn turtlesim/srv/Spawn "{x: 2.0, y: 2.0, theta: 0.2, name: ''}"
requester: making request: turtlesim.srv.Spawn_Request(x=2.0, y=2.0, theta=0.2, name='')
response:
turtlesim.srv.Spawn_Response(name='turtle2')