12. Custom Service

ในบทนี้เราจะเรียนรู้การสร้าง Service แบบกำหนดเอง (Custom Service) ซึ่งเป็นรูปแบบการสื่อสาร ระหว่างโหนด (Node) ในลักษณะ “ถาม–ตอบ” (Request–Response)

12.1. สร้างไฟล์.srv

เปิด VS Code ขึ้นมา สร้างโฟลเดอร์ srv

_images/12.1.1.png

สร้างไฟล์ AddTwoInts.srv

_images/12.1.2.png

เพิ่มเนื้อหาในไฟล์ AddTwoInts.srv

int64 a
int64 b
---
int64 sum
_images/12.1.3.png

เพิ่มเนื้อหาใน CMakeList.txt

find_package(rosidl_default_generators REQUIRED)
rosidl_generate_interfaces(${PROJECT_NAME}
 "msg/RobotStatus.msg"
 "srv/AddTwoInts.srv"
)
_images/12.1.4.png

เปิด Terminal ขึ้นมา เพื่อทำการ คอมไพล์

cd ~/ros2_ws
colcon build 
_images/12.1.5.png

ตรวจสอบว่า service ถูกสร้างสำเร็จ

ros2 interface show custom_tutorials/srv/AddTwoInts
_images/12.1.6.png

12.2. ทดลองใช้ Custom Service ที่เราสร้างไว้ (AddTwoInts.srv)

สร้าง โหนด add_two_ints_server.py และ add_two_ints_client.py ภายใน my_package

_images/12.2.1.png

ตัวอย่างโค้ด add_two_ints_server.py

import rclpy
from rclpy.node import Node
from custom_tutorials.srv import AddTwoInts

class AddTwoIntsServer(Node):
    def __init__(self):
        super().__init__('add_two_ints_server')
        self.srv = self.create_service(AddTwoInts, 'add_two_ints', self.callback)

    def callback(self, request, response):
        response.sum = request.a + request.b
        self.get_logger().info(f'Request: {request.a} + {request.b} = {response.sum}')
        return response

def main():
    rclpy.init()
    node = AddTwoIntsServer()
    rclpy.spin(node)
    rclpy.shutdown()

if __name__ == '__main__':
    main()

ตัวอย่างโค้ด add_two_ints_client.py

import rclpy
from rclpy.node import Node
from custom_tutorials.srv import AddTwoInts

class AddTwoIntsClient(Node):
    def __init__(self):
        super().__init__('add_two_ints_client')
        self.client = self.create_client(AddTwoInts, 'add_two_ints')

        while not self.client.wait_for_service(timeout_sec=1.0):
            self.get_logger().info('Waiting for service...')

    def send_request(self, a, b):
        req = AddTwoInts.Request()
        req.a = a
        req.b = b
        future = self.client.call_async(req)
        rclpy.spin_until_future_complete(self, future)
        return future.result()

def main():
    rclpy.init()
    node = AddTwoIntsClient()
    response = node.send_request(3, 7)
    node.get_logger().info(f'Result: {response.sum}')
    rclpy.shutdown()

if __name__ == '__main__':
    main()

ตั้งค่า setup.py

'add_two_ints_server = my_package.add_two_ints_server:main',
'add_two_ints_client = my_package.add_two_ints_client:main',
_images/12.2.2.png

เปิด Terminal ขึ้นมา ทำการ คอมไพล์

cd ~/ros2_ws
colcon build
_images/12.2.3.png

ทดสอบการทำงานของโหนด add_two_ints_server และ add_two_ints_client กับ AddTwoInts Service

ros2 run my_package add_two_ints_server
ros2 run my_package add_two_ints_client
_images/12.2.4.png