참고
https://docs.ros.org/en/foxy/Tutorials/Writing-A-Simple-Py-Service-And-Client.html
패키지 생성 및 코드 data 저장
~/워크스페이스/src 에 드가서 이거 치삼
srv는 기본예제 weget으로 안받고 패키지 만들고 직접 editor로 작성해서 진행 할거임.!
ros2 pkg create --build-type ament_python py_srvcli --dependencies rclpy example_interfaces
저거 세개 수정해줄 거 해주고 (이름 이메일 파일설명 라이센스)
코드
~/ws_2/src/py_srvcli/py_srvcli$ 안에 들어가서 직접 editor 로 작성
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()
~/ws_2/src/py_srvcli/py_srvcli$ 안에 들어가서 직접 editor 로 작성
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()
코드설명
코드설명 전에 알아 둬야 하는 내용들
- 1
클라이언트의 메인에서 유일하게 중요한 차이점은 while 루프입니다. 루프는 시스템이 실행되는 동안 서비스로부터 응답이 있는지 확인하기 위해 future 를 확인합니다. 서비스에서 응답을 보낸 경우 결과가 로그 메시지에 기록됩니다.
- 2
클라이언트 노드에서 call_async() API를 사용하여 서비스를 호출했고, 서비스를 호출할 다양한 방법(API)가 있습니다.
- 3
https://docs.ros2.org/latest/api/rclpy/api/services.html
client <--------> server 간의 data 전송 방식에 대한 설명이 나온 사이트 참고해라
순서도
server -> dds 네이밍올림
client -> dds 네이밍올림 -> 대기상태( wait_for_service )
dds -> client -- server -네이밍 맞춰서 연결
client.request -> server
( 클라이언트노드객체명.future.XXX future 클래스가 중요함. 클라이언트.future.done() 함수로 통신양호한지 확인도 하고, 클라이언트.future.result() 함수로 server로부터 받는 response도 가져오기도 하고 함. )
server.response -> client
client.destroy_node()
내용정리
------------------------------------------메시지 타입 정의 부분 --------------------------------------------------
service 와 client 가 사용한 메시지 타입은 String 이다.
메시지 타입을 사용하려면 방법이 2개 있다.
1. 직접 만드는방법
2. ros2 깔면서 자동으로 받아지는 lib 쓰기
여기서 쓴 방법은 2번이다.
하는방법
1_1.
ros2 pkg create --build-type ament_python py_srvcli --dependencies rclpy example_interfaces
생성할 때 디펜던시 의존성을 넣어 주든가
1_2.
package.xml 에 의존성 명시 해줘야한다.
밑에 그림 3번 부분 처럼 <depend>example_interfaces</depend>
1_3
python 코드짤 때, 위에 그림에 1,2 번처럼
from example_interfaces.srv import AddTwoInts
------------------------------------------순서도 설명 --------------------------------------------------
1~4 까지는 네이밍 부분이라 누가 먼저 실행하냐 얘기임 그래서 동일하게 1~4 했고
그리고 어느부분에서 순서도 동작을 하는지 정리해봄
server -> dds 네이밍올림
3 (네임)
client -> dds 네이밍올림 -> 대기상태( wait_for_service )
3 (네임)
dds -> client -- server -네이밍 맞춰서 연결
4 , 4 (토픽,메시지타입)
client.request -> server
9 ( call_async(self.req) )
server.response -> client
12 ( return respone )
client.destroy_node()
16 관련노드 제거
~/ws_2/src/py_srvcli 에 드가서
새로 작성한 python 코드들 명시 해주고
entry_points={
'console_scripts': [
'service = py_srvcli.service_member_function:main',
'client = py_srvcli.client_member_function:main',
],
},
종속성 맞춰서 깔아주공
rosdep install -i --from-path src --rosdistro foxy -y
이거 아니면 걍 colcon build 로 전부 해줘도 ㄱㅊ
colcon build --packages-select py_srvcli
colcon build --packages-select "콜콘할 패키지명"
. install/setup.bash
service 노드 실행
ros2 run py_srvcli service
client 노드 실행 (인자 2개 넘겨줘야함 , 서비스에서 더해서 프린팅해중꼐)
ros2 run py_srvcli client 2 3
츨력값
[INFO] [minimal_client_async]: Result of add_two_ints: for 2 + 3 = 5
'ros2_python > Ros2 msg,srv,action,parm' 카테고리의 다른 글
ros2_msg 토픽 example(executor사용==멀티쓰레드) (0) | 2022.07.05 |
---|---|
ros2_msg 토픽 example(executor사용==싱글쓰레드) (0) | 2022.06.28 |
ros2_python코드에서 param 데이터 사용법 (0) | 2022.04.27 |
사용자 정의 ros2 msg, srv파일 구성 (0) | 2022.04.27 |
ros2_msg 토픽 example(상속으로==싱글스레드) (0) | 2022.04.25 |
댓글