Divide and Conquer

서비스 패키지 생성 본문

2025/ROS

서비스 패키지 생성

10살 2022. 8. 17. 14:09
728x90

이름 잘 보고 수정 ㄱㄱ

cd ~/catkin_ws/src
catkin_create_pkg 패키지명 std_msgs roscpp rospy

sudo apt-get install tree
tree -L 2 -d

CMakeLists.txt: 빌드 설정 파일
package.xml: 패키지의 정보

CMakeLists.txt

cmake_minimum_required(VERSION 3.0.2)
project(service_test)

# 캐킨 빌드 요구되는 구성요소 패키지
find_package(catkin REQUIRED COMPONENTS
  message_generation
  roscpp
  rospy
  std_msgs
)

#add_message_files(
#  FILES
#  Num.msg
#)

# 서비스 선언
add_service_files(
  FILES
  AddTwoInts.srv
)

# 의존하는 메시지 설정하는 옵션
generate_messages(
  DEPENDENCIES
  std_msgs
)

# 캐킨 패키지 옵션
catkin_package(
#  INCLUDE_DIRS include
  LIBRARIES service_test
  CATKIN_DEPENDS roscpp rospy std_msgs
#  DEPENDS system_lib
#  CATKIN_DEPENDS message_runtime
)

# 인클루드 디렉터리
include_directories(
# include
  ${catkin_INCLUDE_DIRS}
)

# add_two_ints_server 노드에 대한 빌드 옵션
add_executable(add_two_ints_server src/add_two_ints_server.cpp)
add_dependencies(add_two_ints_server ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(add_two_ints_server ${catkin_LIBRARIES})

add_executable(add_two_ints_client src/add_two_ints_client.cpp)
add_dependencies(add_two_ints_client ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(add_two_ints_client ${catkin_LIBRARIES})

http://wiki.ros.org/ROS/Tutorials/CreatingMsgAndSrv
빌드를 진행할땐 message_generation이 필요하고 실행을 할땐 message_runtime이 필요
https://doongdoongeee.tistory.com/96

package.xml

<?xml version="1.0"?>
<package format="2">
  <name>service_test</name>
  <version>0.0.0</version>
  <description>The service_test package</description>

  <maintainer email="jetbot@todo.todo">jetbot</maintainer>
  <license>TODO</license>

  <buildtool_depend>catkin</buildtool_depend>
    
  <build_depend>message_generation</build_depend> 
  <build_depend>roscpp</build_depend>
  <build_depend>rospy</build_depend>
  <build_depend>std_msgs</build_depend>
    
  <build_export_depend>roscpp</build_export_depend>
  <build_export_depend>rospy</build_export_depend>
  <build_export_depend>std_msgs</build_export_depend> 
    
  <exec_depend>roscpp</exec_depend>
  <exec_depend>rospy</exec_depend>
  <exec_depend>std_msgs</exec_depend>
  <exec_depend>message_runtime</exec_depend>  

  <!-- The export tag contains other, unspecified, tags -->
  <export>
    <!-- Other tools can request additional information be placed here -->

  </export>
</package>

srv/AddTwoInts.srv

int64 a
int64 b
---
int64 sum

src/add_two_ints_server.cpp

#include "ros/ros.h" // ROS 기본 헤더 파일
#include "service_test/AddTwoInts.h" // AddTwoInts 서비스 파일 헤드(빌드 후 자동생성됨)

// 서비스 요청이 있으면 아래 실행
bool add(service_test::AddTwoInts::Request  &req,
         service_test::AddTwoInts::Response &res)
{

  // 서비스 요청 시 더해 응답값에 저장
  res.sum = req.a + req.b;
  ROS_INFO("request: x=%ld, y=%ld", (long int)req.a, (long int)req.b);
  ROS_INFO("sending back response: [%ld]", (long int)res.sum);
    
  return true;
}

int main(int argc, char **argv) // 노드 메인함수
{
  ros::init(argc, argv, "add_two_ints_server"); // 노드명 초기화
  ros::NodeHandle n; // 노드 핸들 선언

  // 서비스 서버 선언(service), cake는 서비스명이고 서비스 요청이 있을 때 add 실행
  ros::ServiceServer server = n.advertiseService("cake", add);
  ROS_INFO("Ready to service server");
  
  ros::spin(); //요청이 올때까지 기다린다.spin 

  return 0;
}

src/add_two_ints_client.cpp

#include "ros/ros.h" // 기본 헤더 파일
#include "service_test/AddTwoInts.h"
#include <cstdlib> //atoll 이라는 함수를 쓰려고 넣어준 라인

int main(int argc, char **argv) // 노드 메인함수
{
  ros::init(argc, argv, "add_two_ints_client");

  if (argc != 3) // 입력값 오류 처리, 요청시 노드이름 , 숫자1 , 숫자2로 요청하기때문에 3개가 되어야한다.(예제)
  {
    ROS_INFO("usage: add_two_ints_client X Y");
    return 1;
  }

  ros::NodeHandle n; // ROS 시스템과 통신을 위한 노드 핸들 선언

  // cake는 서비스명
  ros::ServiceClient client = n.serviceClient<service_test::AddTwoInts>("cake");

  // srv라는 이름으로 AddTwoInts 서비스 파일을 이용하는 서비스 선언
  service_test::AddTwoInts srv;
  srv.request.a = atoll(argv[1]); //atoll은 입력되는 값을 분리하는 함수.
  srv.request.b = atoll(argv[2]);

  // 서비스를 요청하고, 요청이 받아들여진 경우 응답값 표시
  if (client.call(srv)) // 요청을 보내는곳
  {
    ROS_INFO("send srv, srv.Request.a and b: %ld, %ld", (long int)srv.request.a, (long int)srv.request.b);
    ROS_INFO("receive srv, srv.Respond.result: %ld", (long int)srv.response.sum);
  }
  else
  {
    ROS_ERROR("Failed to call service add_two_ints");
    return 1;
  }

  return 0;
}

파이썬 코드

더보기

add_two_ints_server.py

#!/usr/bin/env python

from service_test.srv import *
import rospy

def handle_add_two_ints(req):
    print "Returning [%s + %s = %s]"%(req.a, req.b, (req.a + req.b))
    return AddTwoIntsResponse(req.a + req.b)

def add_two_ints_server():
    rospy.init_node('add_two_ints_server')
    s = rospy.Service('add_two_ints', AddTwoInts, handle_add_two_ints)
    print "Ready to add two ints."
    rospy.spin()

if __name__ == "__main__":
    add_two_ints_server()

add_two_ints_client.py

#!/usr/bin/env python

import sys
import rospy
from service_test.srv import *

def add_two_ints_client(x, y):
    rospy.wait_for_service('add_two_ints')
    try:
        add_two_ints = rospy.ServiceProxy('add_two_ints', AddTwoInts)
        resp1 = add_two_ints(x, y)
        return resp1.sum
    except rospy.ServiceException, e:
        print "Service call failed: %s"%e

def usage():
    return "%s [x y]"%sys.argv[0]

if __name__ == "__main__":
    if len(sys.argv) == 3:
        x = int(sys.argv[1])
        y = int(sys.argv[2])
    else:
        print usage()
        sys.exit(1)
    print "Requesting %s+%s"%(x, y)
    print "%s + %s = %s"%(x, y, add_two_ints_client(x, y))

빌드

roscore

rosrun service_test add_two_ints_server

rosrun service_test add_two_ints_client 2 3
=rosservice call /cake 2 3
에러 나면 
cd catkin_ws && source devel/setup.bash

 

실행 영상

 

 

https://gradient-descent.tistory.com/71

반응형

'2025 > ROS' 카테고리의 다른 글

ros EasyInstallDeprecationWarning: easy_install command is deprecated.  (0) 2023.04.11
Ubuntu 20.04 ROS2 Foxy install  (0) 2022.09.24
ROS Setting Alias  (0) 2022.08.17
Fusion 360 file to ROS URDF  (0) 2022.08.08
Window에 ROS 설치  (0) 2022.08.08
Comments