차이
문서의 선택한 두 판 사이의 차이를 보여줍니다.
| 다음 판 | 이전 판 | ||
| activity:public:2021:ros:5 [2021/09/28 20:51:47] – 만듦 yhy01625 | activity:public:2021:ros:5 [2021/10/03 15:47:58] (현재) – yhy01625 | ||
|---|---|---|---|
| 줄 1: | 줄 1: | ||
| + | ======ROS STUDY #5 : ROS 기초프로그래밍 2(service)====== | ||
| + | |||
| + | {{youtube> | ||
| + | =====1. Service 패키지 생성===== | ||
| + | <sxh bash> | ||
| + | cd ~/ | ||
| + | catkin_create_pkg ros_tutorials_service message_generation message_runtime roscpp std_msgs | ||
| + | // | ||
| + | </ | ||
| + | |||
| + | 캐킨 명령어로 패키지를 생성하면 src 폴더 아래 다음과 같은 폴더와 파일들이 생성된다. 아래의 명령어로 해당 패키지 폴더로 이동하여 확인할 수 있다. | ||
| + | <sxh bash> | ||
| + | cd ros_tutorials_service | ||
| + | ls | ||
| + | </ | ||
| + | |||
| + | include → 헤더 파일 폴더 | ||
| + | src → 소스 코드 폴더 | ||
| + | CMakeLists.txt → 빌드 설정 파일 | ||
| + | package.xml → 패키지 설정 파일 | ||
| + | \\ | ||
| + | ====1.1. package.xml==== | ||
| + | 기본 뼈대만 적힌 패키지 설정 파일(package.xml)을 열어 추가 정보를 기입하자.\\ | ||
| + | 터미널에 다음 코드를 입력하여 파일을 열자. | ||
| + | <sxh bash> | ||
| + | gedit package.xml | ||
| + | </ | ||
| + | |||
| + | Visual Studio Code로 파일을 열고 싶다면 이 코드를 사용하자. | ||
| + | <sxh bash> | ||
| + | code package.xml | ||
| + | </ | ||
| + | |||
| + | <sxh xml; highlight: [19-19, | ||
| + | <!-- 패키지 형식 --> | ||
| + | <package format=" | ||
| + | <!-- 패키지 이름 --> | ||
| + | < | ||
| + | <!-- 패키지 버전(나중에 배포할 시 업데이트 하며 수정하면 됨) --> | ||
| + | < | ||
| + | <!-- 패키지 설명 --> | ||
| + | < | ||
| + | <!-- 패키지를 유지, 보수 하는 사람의 연락처 --> | ||
| + | < | ||
| + | <!-- 라이센스 입력하는 곳(Apach 2.0, BSD 등) --> | ||
| + | < | ||
| + | | ||
| + | <!-- 패키지를 빌드하는 데 사용되는 툴 --> | ||
| + | < | ||
| + | |||
| + | <!-- 빌드시 사용되는 의존성 패키지 --> | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | |||
| + | <!-- 실행파일 빌드시 사용되는 의존성 패키지(src폴더의 파일들이 노드 실행파일로 만들어질 때 사용되는 패키지) --> | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | |||
| + | <!-- 빌드 후 실행시 사용되는 의존성 패키지 --> | ||
| + | < | ||
| + | < | ||
| + | < | ||
| + | |||
| + | < | ||
| + | </ | ||
| + | </ | ||
| + | \\ | ||
| + | ====1.2. CMakeLists.txt==== | ||
| + | 빌드 설정 파일(CMakeLists.txt)에는 작성한 노드를 빌드할 때, 즉 소스코드 작성 후 실행파일을 만들때 사용되는 옵션들이 적혀 있다. 해당 파일을 열어 다음과 같이 수정하자. | ||
| + | <sxh bash> | ||
| + | gedit CMakeLists.txt | ||
| + | </ | ||
| + | |||
| + | <sxh cpp; highlight: [17-20], | ||
| + | ## cmake의 최소 요구 버전 | ||
| + | cmake_minimum_required(VERSION 3.0.2) | ||
| + | ## 패키지 이름과 동일, 이름과 다르면 빌드가 안된다. | ||
| + | project(ros_tutorials_service) | ||
| + | |||
| + | ## 의존성 패키지 | ||
| + | ## 캐킨 빌드를 할 때 요구되는 구성요소 패키지이다. | ||
| + | ## 의존성 패키지로 message_generation, | ||
| + | find_package(catkin REQUIRED COMPONENTS | ||
| + | message_generation | ||
| + | message_runtime | ||
| + | roscpp | ||
| + | std_msgs | ||
| + | ) | ||
| + | |||
| + | ## 새로 만들 메세지 이름 (58번째 줄 수정) | ||
| + | add_service_files( | ||
| + | FILES | ||
| + | SrvTutorial.srv | ||
| + | ) | ||
| + | |||
| + | ## 의존성 (71번째 줄 수정) | ||
| + | ## 의존하는 메시지를 설정하는 옵션이다. | ||
| + | ## std_msgs가 설치되어 있지 않다면 빌드 도중에 에러가 난다. | ||
| + | generate_messages( | ||
| + | DEPENDENCIES | ||
| + | std_msgs | ||
| + | ) | ||
| + | |||
| + | ##캐킨 패키지 옵션으로 라이브러리, | ||
| + | catkin_package( | ||
| + | LIBRARIES ros_tutorials_service | ||
| + | CATKIN_DEPENDS message_generation message_runtime roscpp std_msgs | ||
| + | ) | ||
| + | |||
| + | ## 인클루드 디렉터리를 설정한다. | ||
| + | include_directories( | ||
| + | ${catkin_INCLUDE_DIRS} | ||
| + | ) | ||
| + | |||
| + | ## service_server 노드에 대한 빌드 옵션이다. | ||
| + | ## 실행 파일, 타겟 링크 라이브러리, | ||
| + | ## service_server: | ||
| + | ## 136번째 줄 수정 | ||
| + | add_executable(service_server src/ | ||
| + | ## 146번째 줄 수정 | ||
| + | add_dependencies(service_server ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) | ||
| + | ## 149번째 줄 수정 | ||
| + | target_link_libraries(service_server ${catkin_LIBRARIES}) | ||
| + | |||
| + | ## service_client 노드에 대한 빌드 옵션이다. | ||
| + | ## service_client: | ||
| + | ## 151번째 줄에 추가로 작성 | ||
| + | add_executable(service_client src/ | ||
| + | add_dependencies(service_client ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) | ||
| + | target_link_libraries(service_client ${catkin_LIBRARIES}) | ||
| + | </ | ||
| + | \\ | ||
| + | =====2. 서비스 파일(srv) 작성===== | ||
| + | 아래 코드를 통해 srv 폴더를 만들고, 그 폴더로 이동하여 SrvTutorial.srv 파일을 새로 만들어 내용을 추가하자. | ||
| + | <sxh bash> | ||
| + | mkdir srv | ||
| + | cd srv | ||
| + | gedit SrvTutorial.srv | ||
| + | </ | ||
| + | |||
| + | <sxh cpp title: | ||
| + | int64 a | ||
| + | int64 b | ||
| + | --- | ||
| + | int64 result | ||
| + | </ | ||
| + | |||
| + | * int64 : 메세지 자료형 | ||
| + | * a, b : 서비스 요청(request) | ||
| + | * result : 서비스 응답(response) | ||
| + | * '' | ||
| + | \\ | ||
| + | =====3. 서비스 노드 코드 작성===== | ||
| + | ====3.1. 서버(server)==== | ||
| + | 아래 코드를 통해 소스 폴더로 이동해 service_server.cpp 파일을 새로 만들고 내용을 수정하자. | ||
| + | <sxh bash> | ||
| + | roscd ros_tutorials_service/ | ||
| + | gedit service_server.cpp | ||
| + | </ | ||
| + | |||
| + | <sxh cpp title: | ||
| + | #include " | ||
| + | #include " | ||
| + | |||
| + | // 서비스 요청이 있을 경우, 아래의 처리를 수행한다. | ||
| + | // 서비스 요청은 req, 서비스 응답은 res로 설정하였다. | ||
| + | bool calculation(ros_tutorials_service:: | ||
| + | { | ||
| + | // 서비스 요청시 받은 a와 b 값을 더하여 서비스 응답 값에 저장한다. | ||
| + | res.result = req.a + req.b; | ||
| + | |||
| + | // 서비스 요청에 사용된 a, b 값의 표시 및 서비스 응답에 해당되는 result 값을 출력한다. | ||
| + | ROS_INFO(" | ||
| + | ROS_INFO(" | ||
| + | |||
| + | return true; | ||
| + | } | ||
| + | |||
| + | int main(int argc, char **argv) | ||
| + | { | ||
| + | ros:: | ||
| + | ros:: | ||
| + | |||
| + | // 서비스 서버 선언, ros_tutorials_service 패키지의 SrvTutorial 서비스 파일을 이용한 서비스 서버 ros_tutorials_service_server를 선언한다. | ||
| + | // 서비스명은 ros_tutorial_srv이며 서비스 요청이 있을 때, calculation라는 함수를 실행하라는 설정이다. | ||
| + | ros:: | ||
| + | |||
| + | ROS_INFO(" | ||
| + | |||
| + | ros:: | ||
| + | |||
| + | return 0; | ||
| + | } | ||
| + | </ | ||
| + | \\ | ||
| + | ====3.2. 클라이언트(client)==== | ||
| + | 위에서처럼 service_client.cpp 파일을 새로 만들고 내용을 수정하자. | ||
| + | <sxh bash> | ||
| + | gedit service_client.cpp | ||
| + | </ | ||
| + | |||
| + | <sxh cpp title: | ||
| + | #include " | ||
| + | #include " | ||
| + | #include < | ||
| + | |||
| + | int main(int argc, char **argv) | ||
| + | { | ||
| + | ros:: | ||
| + | |||
| + | if (argc != 3) // 입력값 오류 처리 | ||
| + | { | ||
| + | ROS_INFO(" | ||
| + | ROS_INFO(" | ||
| + | |||
| + | return 1; | ||
| + | } | ||
| + | |||
| + | ros:: | ||
| + | |||
| + | // 서비스 클라이언트 선언, ros_tutorials_service 패키지의 SrvTutorial 서비스 파일을 이용한 서비스 클라이언트 ros_tutorials_service_client를 선언한다. | ||
| + | // 서비스명은 " | ||
| + | ros:: | ||
| + | |||
| + | // srv라는 이름으로 SrvTutorial 서비스 파일을 이용하는 서비스를 선언한다. | ||
| + | ros_tutorials_service:: | ||
| + | |||
| + | // 서비스 요청 값으로 노드가 실행될 때 입력으로 사용된 매개변수를 각각의 a, b에 저장한다. | ||
| + | srv.request.a = atoll(argv[1]); | ||
| + | srv.request.b = atoll(argv[2]); | ||
| + | |||
| + | // 서비스를 요청하고, | ||
| + | if (ros_tutorials_service_client.call(srv)) | ||
| + | { | ||
| + | ROS_INFO(" | ||
| + | ROS_INFO(" | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | ROS_ERROR(" | ||
| + | |||
| + | return 1; | ||
| + | } | ||
| + | |||
| + | return 0; | ||
| + | } | ||
| + | </ | ||
| + | \\ | ||
| + | =====4. ROS 노드 빌드===== | ||
| + | 다음 명령어로 ros_tutorials_service 패키지의 서비스 파일, 서비스 서버 노드와 클라이언트 노드를 빌드한다. | ||
| + | <sxh bash> | ||
| + | cd ~/catkin_ws && catkin_make | ||
| + | </ | ||
| + | \\ | ||
| + | =====5. 서비스 노드 실행===== | ||
| + | ====5.1. 서비스 서버 실행==== | ||
| + | roscore을 실행한 뒤 다음 코드로 서비스 서버를 실행한다. | ||
| + | <sxh bash> | ||
| + | rosrun ros_tutorials_service service_server | ||
| + | </ | ||
| + | |||
| + | [INFO] [1495726541.268629564]: | ||
| + | \\ | ||
| + | ====5.2. 서비스 클라이언트 실행==== | ||
| + | 마찬가지로 서비스 클라이언트를 실행하자. | ||
| + | <sxh bash> | ||
| + | rosrun ros_tutorials_service service_client 2 3 | ||
| + | </ | ||
| + | |||
| + | [INFO] [1495726543.277216401]: | ||
| + | [INFO] [1495726543.277258018]: | ||
| + | |||