[ROS2] (17)-Python으로 서비스와 클라이언트 만들기
서비스와 클라이언트 만들기
이전 포스팅에서 만들었던 서비스와 클라이언트 노드를 python으로 만들어보자.
패키지 만들기
먼저, 패키지를 만든다.
$ cd dev_ws/src
$ ros2 pkg create --build-type ament_python py_srvcli --dependencies rclpy example_interfaces
--dependencies
는 package.xml
에 dependency를 추가해준다.
서비스 노드 작성하기
다음으로 dev_ws/src/py_srvcli/py_srvcli
폴더에 service_member_function.py
파일을 만들고, 아래 코드를 붙여넣는다.
$ cd dev_ws/src/py_srvcli/py_srvcli
$ gedit service_member_function.py
from example_interfaces.srv import AddTwoInts
import rclpy
from rclpy.node import Node
class MinimalService(Node):
def __init__(self):
super().__init__('minimal_service')
self.srv = self.create_service(AddTwoInts, 'add_two_ints', self.add_two_ints_callback)
def add_two_ints_callback(self, request, response):
response.sum = request.a + request.b
self.get_logger().info('Incoming request\na: %d b: %d' % (request.a, request.b))
return response
def main(args=None):
rclpy.init(args=args)
minimal_service = MinimalService()
rclpy.spin(minimal_service)
rclpy.shutdown()
if __name__ == '__main__':
main()
코드를 보면, 가장 먼저 필요한 패키지를 import 해주고 있다. 다음으로 MinimalService
라는 클래스에서 생성자와 callback 함수를 정의해준다.
ros2 run
이 노드를 찾을 수 있도록 setup.py
파일에서 'console_scripts':
괄호 안에 아래 내용을 추가한다.
'service = py_srvcli.service_member_function:main',
클라이언트 노드 작성하기
dev_ws/src/py_srvcli/py_srvcli
폴더 안에 client_member_function.py
파일을 만들고, 아래 내용을 붙여넣는다.
import sys
from example_interfaces.srv import AddTwoInts
import rclpy
from rclpy.node import Node
class MinimalClientAsync(Node):
def __init__(self):
super().__init__('minimal_client_async')
self.cli = self.create_client(AddTwoInts, 'add_two_ints')
while not self.cli.wait_for_service(timeout_sec=1.0):
self.get_logger().info('service not available, waiting again...')
self.req = AddTwoInts.Request()
def send_request(self):
self.req.a = int(sys.argv[1])
self.req.b = int(sys.argv[2])
self.future = self.cli.call_async(self.req)
def main(args=None):
rclpy.init(args=args)
minimal_client = MinimalClientAsync()
minimal_client.send_request()
while rclpy.ok():
rclpy.spin_once(minimal_client)
if minimal_client.future.done():
try:
response = minimal_client.future.result()
except Exception as e:
minimal_client.get_logger().info(
'Service call failed %r' % (e,))
else:
minimal_client.get_logger().info(
'Result of add_two_ints: for %d + %d = %d' %
(minimal_client.req.a, minimal_client.req.b, response.sum))
break
minimal_client.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
클라이언트 노드는 sys.argv
로 input 을 받기 위해 sys
모듈을 포함한다. 생성자 내부의 while
문은 클라이언트가 요청하는 서비스가 이용가능한지 확인한다. main
함수의 while
문은 future
를 체크해서 응답이 왔는지를 확인한다.
역시 setup.py
파일에서 'console_scripts':
괄호 내에 아래 내용을 추가한다.
'client = py_srvcli.client_member_function:main',
빌드 및 실행하기
dependency를 먼저 확인한다.
$ cd dev_ws
$ rosdep install -i --from-path src --rosdistro foxy -y
빌드한다.
$ cd dev_ws
$ colcon build --packages-select py_srvcli
서비스 노드를 실행한다.
$ source install/setup.bash
$ ros2 run py_srvcli service
클라이언트 노드를 실행하면서 정수를 서버에 넘겨 준다.
$ source install/setup.bash
$ ros2 run py_srvcli client 2 3
이전 포스팅에서 만든 클라이언트 노드도 실행해보자.
$ source install/setup.bash
$ ros2 run cpp_srvcli client 5 10
역시 작성한 언어에 관계 없이 잘 동작하는 것을 확인할 수 있다.
댓글남기기