티스토리 뷰

자율주행 로봇

[ROS]Introduction to msg and srv

무엇보다_빛나는_샤트 2022. 1. 15. 17:08

안녕하세요

자율주행 로봇 전문가를 향해 나아가는 빛나는 샤트입니다.

본 글은 ROS/Tutorials/CreatingMsgAndSrv 글을 해석/편집한 글입니다.

1. msg와 srv 소개

  • msg: msg파일은 ROS 메세지를 표현하는 간단한 텍스트 파일이다. 이들은 다른 언어로 쓰여진 소스코드들을 동작할 수 있게 해준다.
  • srv: srv파일은 서비스(*service)를 표현한다. 이들은 요청(request)과 응답(response)으로 구성되어 있다.
    *service: ROS 노드들끼리 통신하는 방법 중 하나.

msg파일은 msg 디렉토리 내부에 저장되어 있고, srv파일은 srv 디렉토리 내부에 저장되어 있다.
msg파일들은 필드 타입과 필드 이름을 각 줄마다 가지고 있는 간단한 텍스트 파일이다. 필드 타입은 아래와 같다:

  • int8, int16, int32, int64 (plus uint*)
  • float32, float64
  • string
  • time, duration
  • other msg files
  • variable-length array[] and fixed-length array[C]

여기에는 ROS 내부의 특별한 타입도 있는데, Header이다. header는 timestamp와 좌표 프레임정보(ROS에서 공통적으로 사용)를 포함하고 있다.

Header를 사용하는 msg 예시는 아래와 같다. 여기에서는 _Header, string primitive, 두 개의 다른 msg_를 사용했다.

Header header
string child_frame_id
geometry_msgs/PoseWithCovariance pose
geometry_msgs/TwistWithCovariance twist

srv파일은 요청과 응답을 제외하면 msg파일과 비슷합니다. 요청과 응답은 '---'로 구분됩니다.
srv파일의 예시는 아래와 같다.

int64 A
int64 B
---
int64 sum

위의 예시에서는 A,B가 요청이고 Sum이 응답이다.

2. msg 사용하기

2.1 msg 만들기

이전 튜토리얼에서 생성한 패키지를 이용해 새로운 msg 파일을 생성하자.

$ roscd beginner_tutorials
$ mkdir msg
$ echo "int64 num" > msg/Num.msg

위에서 생성한 msg파일은 1줄 밖에 없지만 더 복잡하게 생성 가능하다. 예시는 아래와 같다.

string first_name
string last_name
uint8 age
uint32 score

한 가지 더 있는데, 우리는 msg 파일들이 C++, Python 을 포함한 다양한 언어들을 소스코드로 변환해야한다.
package.xml 파일을 열어서 아래 두 줄을 추가하고 주석 해제한다.

<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>

빌드 시간에는 "message_generation"이 필요하고 런타임동안에는 "message_runtime"가 필요하다.

당신이 사용하기 편한 텍스트 편집기를 이용해 CMakeLIsts.txt를 열어라.
그리고 find_packagemessage_generation dependency를 추가해라. 그러면 메세지를 생성할 수 있게 된다.
COMPONENTS에 간단하게 추가할 수 있다. 아래 예시를 보자.

# Do not just add this to your CMakeLists.txt, modify the existing text to add message_generation before the closing parenthesis
find_package(catkin REQUIRED COMPONENTS
   roscpp
   rospy
   std_msgs
   message_generation
)

가끔 find_package에 제대로 dependency들을 추가하지 않아도 프로젝트가 잘 빌드되는 것을 알 수 있다. 왜냐하면 이것은 catkin은 모든 프로젝트를 하나로 합쳐서 (만약 이전 프로젝트가 find_package를 call했다면) 당신의 프로젝트들은 같은 값으로 정의됐을 것이다. 하지만 이럴 경우 프로젝트가 쉽게 break될 수 있음을 잊지 말자.

또한 message runtime dependency를 export해야 한다.

catkin_package(
  ...
  CATKIN_DEPENDS message_runtime ...
  ...)

아래의 코드 블록을 찾아라.

# add_message_files(
#   FILES
#   Message1.msg
#   Message2.msg
# )

#을 제거해 주석 해제를 하고 당신이 생성한 .msg 파일을 추가해라. 아래와 같이.

add_message_files(
  FILES
  Num.msg
)

수동으로 .msg 파일을 추가하면 CMake가 당신의 프로젝트의 msg파일들을 재인식하게 된다.
이제 우리는 generate_messages() 함수를 불러와야 한다. 코드는 아래와 같다.

# generate_messages(
#   DEPENDENCIES
#   std_msgs
# )

이는 아래와 같이 구성하면 된다.

generate_messages(
  DEPENDENCIES
  std_msgs
)

3. rosmsg 이용하기

msg 파일을 생성하는 것은 끝났다. ROS가 rosmsg show 명령어를 이용해 어떤 것을 할 수 있는지 확인하자.

$ rosmsg show [message type]

예시:

$ rosmsg show beginner_tutorials/Num

결과는 아래와 같다.

int64 num

만약 당신이 프로젝트 이름이 생각나지 않는다면 그냥 msg 파일 이름만 입력하면 된다.

$ rosmsg show Num

결과:

[beginner_tutorials/Num]:
int64 num

4. srv 이용하기

4.1 srv 생성

srv를 생성하기 위해 우리가 이용했던 패키지를 이용하자.

$ roscd beginner_tutorials
$ mkdir srv

직접 손으로 srv를 만드는 대신 다른 패키지로부터 복사할 수 있다. roscp 명령어는 다른 패키지로부터 복사해 올 때 유용하다.
사용방법:

$ roscp [package_name] [file_to_copy_path] [copy_path]

이제 우리는 rospy_tutorials패키지로부터 서비스를 복사해왔다.

$ roscp rospy_tutorials AddTwoInts.srv srv/AddTwoInts.srv

하나 더 남아 있는데, C++, Python과 다른 언어들을 소스코드로 변환해야한다.
아직 완료하지 않았더라도 package.xml을 열어서 아래 2줄을 추가해라.

<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>

또한 msg 생성에서 했던 것과 같이 CMakeLIsts.txt를 열어서 message_generation dependency를 추가해라.

# Do not just add this line to your CMakeLists.txt, modify the existing line
find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  message_generation
)

또한 package.xml에 서비스 사용을 위한 수정사항을 반영해야 한다.
#을 제거해서 주석해제 후 당신이 작성한 .srv 파일로 대체해라.

# add_service_files(
#   FILES
#   Service1.srv
#   Service2.srv
# )
add_service_files(
  FILES
  AddTwoInts.srv
)

이제 당신은 서비스를 작동시킬 수 있게 되었다.

4.2 rossrv 이용하기

srv 생성하는 것은 끝났다. ROS에서 rossrv show 명령어를 사용하는 것을 알아보자.

사용방법:

$ rossrv show <service type>

예시:

$ rossrv show beginner_tutorials/AddTwoInts

결과:

int64 a
int64 b
---
int64 sum

rosmsg와 비슷해 보인다. 구체적인 패키지 이름을 알지 못해도 서비스 파일들을 확인할 수 있다.

$ rossrv show AddTwoInts
[beginner_tutorials/AddTwoInts]:
int64 a
int64 b
---
int64 sum

[rospy_tutorials/AddTwoInts]:
int64 a
int64 b
---
int64 sum

5. msg와 srv의 공통 스텝

이전 스텝을 전부 다 완료했더라도 CMakeLists.txt를 변경해야 한다.

# generate_messages(
#   DEPENDENCIES
# #  std_msgs  # Or other packages containing msgs
# )

주석해제하고 .msg 파일(당신의 메세지가 사용하고 있는)을 포함하고 있는 패키지를 추가해라.
예시는 아래와 같다.

generate_messages(
  DEPENDENCIES
  std_msgs
)

이제 우리는 우리의 패지키를 다시 생성하기 위해 몇 가지 새로운 메세지를 만들었다.

# In your catkin workspace
$ roscd beginner_tutorials
$ cd ../..
$ catkin_make
$ cd -

어떠한 msg 디렉토리 내부의 msg 파일들은 모든 언어를 작동시킬 수 있다. C++ 메세지 헤더 파일은 ~/catkin_ws/devel/include/beginner_tutorials/ 에서 작동된다. Python 스크립트는 ~/catkin_ws/devel/lib/python2.7/dist-packages/beginner_tutorials/msg에서 생성된다. lisp 파일은 ~/catkin_ws/devel/share/common-lisp/ros/beginner_tutorials/msg/. 에 나타나게 된다.

srv 파일도 비슷하다. C++ 헤더 파일은 메세지 헤더 파일과 동일한 폴더 내에 있고 Python과 Lisp의 경우 srv 폴더 옆에 msg 폴더에 있다.

메세지의 완전한 스펙은 Message Description Language 페이지에서 확인할 수 있다. 당신이 새로운 메세지를 C++ 노드를 이용할거라면, dependency를 노드와 메세지 사이에 선언해야 한다. 관련 내용은 catkin msg/srv build documentation에 있다.

정리

msg 생성 방법

  1. .msg 파일 생성
  2. package.xml 파일을 열어 <build_depend>, <exec_depend> 수정
  3. CMakeLIsts.txt 파일을 열어 find_package에 build dependency(2번의 <build_depend>에 적용한 이름 추가)
  4. CMakeLIsts.txt 파일을 열어 catkin_package에 runtime dependency(2번의 <exec_depend>에 적용한 이름 추가)
  5. CMakeLIsts.txt 파일을 열어 add_message_files 주석 해제 후 .msg 파일 이름 대체
  6. CMakeLIsts.txt 파일을 열어 generate_messages에 주석 해제 후 메세지 이름 추가

srv 생성 방법

  1. .srv 파일 생성 또는 roscp를 이용해 다른 패키지에서 복사해오기
  2. package.xml 파일을 열어 <build_depend>, <exec_depend> 수정
  3. CMakeLIsts.txt 파일을 열어 find_package에 build dependency(2번의 <build_depend>에 적용한 이름 추가)
  4. CMakeLIsts.txt 파일을 열어 add_message_files 주석 해제 후 .msg 파일 이름 대체
LIST
댓글