이 포스트는 이전 포스트에 이어서 ROS2의 Service에 대한 간단한 설명입니다.
이 포스트는 다음 과정을 완료한 후에 참고하시길 바랍니다.
1. Service
- Service는 Node들 간에 통신을 위한 다른 요소입니다.
- Service는 call-and-response 방식으로 동작합니다. (vs Topic: publisher-subscriber)
- Service-Server는 특정 Service-Client가 요청을 한 경우에만 데이터를 제공합니다.
- 1:1 통신 방식으로 요청을 보내고 처리 결과를 확인하는 통신 방식입니다.
- 첫 번째 터미널에서 아래 명령을 실행해서 'turtlesim.launch.py'를 실행합니다.
$ cd ~/Workspace/ros_ws
$ source install/setup.bash
$ ros2 launch ros_tutorial turtlesim.launch.py
- 두 번째 터미널에서 아래 명령을 실행해서 '/turtle1/teleport_absolute' Service를 호출합니다. 아래 그림과 같이 Service를 호출하고 실행 결과를 수신한 것을 확인할 수 있습니다.
$ ros2 service call /turtle1/teleport_absolute turtlesim/srv/TeleportAbsolute "{x: 1.0, y: 1.0, theta: 0.0}"
- 위 명령을 수신한 TurtleBot의 위치가 변경된 것을 확인할 수 있습니다.
- 아래 명령을 실행해서 Service 목록을 확인합니다. 아래 그림과 같이 Service 목록을 확인할 수 있습니다.
$ ros2 service list
- 아래 명령을 실행해서 '/turtle1/teleport_absolute' Service에 전달할 메시지를 확인합니다. 아래 그림과 같이 'turtlesim/srv/TeleportAbsolute'라는 메시지를 주고받는 것을 확인할 수 있습니다.
$ ros2 service type /turtle1/teleport_absolute
- 아래 명령을 실행해서 'turtlesim/srv/TeleportAbsolute' 메시지를 사용하는 Service를 찾아봅니다. 아래 그림과 같이 '/turtle1/teleport_absolute' Service를 찾을 수 있습니다.
$ ros2 service find turtlesim/srv/TeleportAbsolute
- 아래 명령을 실행해서 'turtlesim/srv/TeleportAbsolute' 메시지의 상세정보를 확인합니다. 아래 그림과 같이 'x', 'y', 'theta' 3가지 값으로 구성된 것을 확이할 수 있습니다.
$ ros2 interface show turtlesim/srv/TeleportAbsolute
2. Service - Client
- TurtleBot을 위치를 변경했던 했던 '/turtle1/teleport_absolute' Service를 호출하는 Service Client를 python으로 구현해 보겠습니다.
- 'src/ros_tutorial/package.xml' 파일의 'depend'에 아래 내용을 추가합니다. 아래 그림과 같이 Service Client가 사용할 dependency를 추가했습니다.
<depend>turtlesim</depend>
- 'src/ros_tutorial/setup.py'의 'console_scripts' 부분에 아래 내용을 추가합니다. 아래 그림과 같이 'turtlesim_abs_client'이라는 명령을 등록했습니다.
'turtlesim_abs_client = ros_tutorial.turtlesim_abs_client:main',
- 'src/ros_tutorial/ros_tutorial/turtlesim_abs_client.py' 파일을 만들고 아래와 같이 편집합니다. TurtleBot에 x=10, y=10, theat=1 위치로 이동하도록 'turtlesim/srv/TeleportAbsolute' 메시지를 보내는 코드입니다.
#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from turtlesim.srv import TeleportAbsolute
class TurtlesimAbsoluteClient(Node):
def __init__(self):
super().__init__('turtlesim_abs_client')
self.client = self.create_client(TeleportAbsolute, '/turtle1/teleport_absolute')
while not self.client.wait_for_service(timeout_sec=1.0):
self.get_logger().info('service not available, waiting again...')
self.req = TeleportAbsolute.Request()
def send_request(self, x, y, theta):
self.req.x = x
self.req.y = y
self.req.theta = theta
self.future = self.client.call_async(self.req)
rclpy.spin_until_future_complete(self, self.future)
return self.future.result()
def main(args=None):
rclpy.init(args=args)
client = TurtlesimAbsoluteClient()
client.send_request(10.0, 10.0, 1.0)
client.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
- 첫 번째 터미널에서 아래 명령을 실행해서 컴파일, 환경설정 그리고 'turtlesim.launch.py'를 실행합니다.
$ cd ~/Workspace/ros_ws
$ colcon build --symlink-install
$ source install/setup.bash
$ ros2 launch ros_tutorial turtlesim.launch.py
- 두 번째 터미널에서 아래 명령을 실행해서 'turtlesim_abs_client'을 실행합니다.
$ cd ~/Workspace/ros_ws
$ source install/setup.bash
$ ros2 run ros_tutorial turtlesim_abs_client
- TurtleBot이 입력한 위치로 이동하면서 회전한 것을 확인할 수 있습니다.
3. Service - Server
- '/turtle1/teleport_absolute' Service Server를 python으로 구현해 보겠습니다.
- 'src/ros_tutorial/setup.py' 파일의 'console_scripts' 부분에 아래 내용을 추가합니다.
'turtlesim_abs_server = ros_tutorial.turtlesim_abs_server:main',
- 'src/ros_tutorial/ros_tutorial/turtlesim_abs_server.py' 파일을 만들고 아래와같이 편집합니다.
#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from turtlesim.srv import TeleportAbsolute
class TurtlesimAbsoluteServer(Node):
def __init__(self):
super().__init__('turtlesim_abs_server')
self.client = self.create_service(TeleportAbsolute,
'/turtle1/teleport_absolute',
self.service_callback)
def service_callback(self, request, response):
print('request:', request)
print('response:', response)
return response
def main(args=None):
rclpy.init(args=args)
service = TurtlesimAbsoluteServer()
rclpy.spin(service)
service.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
- 첫 번째 터미널에서 아래 명령을 실행해서 컴파일, 환경설정 그리고 'turtlesim_abs_server'를 실행합니다.
$ cd ~/Workspace/ros_ws
$ colcon build --symlink-install
$ source install/setup.bash
$ ros2 run ros_tutorial turtlesim_abs_server
- 두 번째 터미널에서 아래 명령을 실행해서 'turtlesim_abs_client'을 실행합니다
$ cd ~/Workspace/ros_ws
$ source install/setup.bash
$ ros2 run ros_tutorial turtlesim_abs_client
- 'turtlesim_abs_server'가 실행중인 첫 번째 터미널에 'turtlesim_abs_client'가 보낸 메시지가 출력되는 것을 확인할 수 있습니다.
'로봇 > ROS' 카테고리의 다른 글
URDF를 이용한 간단한 로봇 만들기 (1) (2) | 2023.07.15 |
---|---|
ROS2 Minimal Tutorial - Action (0) | 2023.07.14 |
ROS2 Minimal Tutorial - Topic (0) | 2023.07.14 |
ROS2 Minimal Tutorial - Basic (0) | 2023.07.13 |
Windows에서 Docker를 이용해 ROS2, Gazebo 설치하기 (7) | 2023.07.12 |