Ubuntu ROS 실습(30)

zeusqoi·4일 전

개인공부 - ubuntu

목록 보기
49/56

이번 실습에서는 ROS 2에서 사용하는 Topic, Service, Action 인터페이스의 구조를 학습하고, 직접 사용자 정의 인터페이스 패키지를 생성하여 Message, Service, Action 파일을 작성하였다. 또한 package.xml과 CMakeLists.txt를 설정하고 패키지를 빌드하여 인터페이스를 생성하는 과정을 실습하였다.


1. 인터페이스 패키지 생성

ROS 2에서는 std_msgs, geometry_msgs, sensor_msgs와 같이 이미 만들어진 인터페이스를 사용할 수 있다.

하지만 기존 인터페이스에 필요한 정보가 없는 경우에는 직접 새로운 인터페이스를 생성할 수 있다.

이번 실습에서는 Message, Service, Action을 별도의 패키지에서 관리하기 위해 msg_srv_action_interface_example 패키지를 생성하였다.

cd ~/robot_ws/src

ros2 pkg create --build-type ament_cmake msg_srv_action_interface_example

패키지를 생성한 후 Message, Service, Action을 저장할 디렉터리를 각각 생성하였다.

cd ~/robot_ws/src/msg_srv_action_interface_example

mkdir msg srv action

패키지는 다음과 같은 구조로 구성된다.

msg_srv_action_interface_example/
├── action/
├── include/
├── msg/
├── src/
├── srv/
├── CMakeLists.txt
└── package.xml

2. Message 인터페이스 작성

먼저 msg 디렉터리에 ArithmeticArgument.msg 파일을 생성하였다.

cd ~/robot_ws/src/msg_srv_action_interface_example/msg

nano ArithmeticArgument.msg

다음과 같이 작성하였다.

builtin_interfaces/Time stamp
float32 argument_a
float32 argument_b

msg 인터페이스는 하나의 데이터 영역으로 구성되며, Topic을 통해 전달할 데이터의 형태를 정의한다.

이번 예제에서는 시간 정보와 두 개의 실수형 인자를 정의하였다.


3. Service 인터페이스 작성

다음으로 srv 디렉터리에 ArithmeticOperator.srv 파일을 작성하였다.

cd ~/robot_ws/src/msg_srv_action_interface_example/srv

nano ArithmeticOperator.srv

파일의 내용은 다음과 같다.

# Constants
int8 PLUS = 1
int8 MINUS = 2
int8 MULTIPLY = 3
int8 DIVISION = 4

# Request
int8 arithmetic_operator
---
# Response
float32 arithmetic_result

Service 인터페이스는 ---를 기준으로 Request와 Response가 구분된다.

이번 실습에서는 덧셈, 뺄셈, 곱셈, 나눗셈을 나타내는 상수를 정의하고, 요청으로 연산 종류를 전달하면 연산 결과를 반환하도록 구성하였다.


4. Action 인터페이스 작성

마지막으로 action 디렉터리에 ArithmeticChecker.action 파일을 작성하였다.

cd ~/robot_ws/src/msg_srv_action_interface_example/action

nano ArithmeticChecker.action

다음과 같이 작성하였다.

# Goal
float32 goal_sum
---
# Result
string[] all_formula
float32 total_sum
---
# Feedback
string[] formula

Action 인터페이스는 ---를 두 번 사용하여 Goal, Result, Feedback 세 영역으로 구분된다.

이번 예제에서는 목표값을 goal_sum으로 전달하고, 결과로 전체 계산식과 총합을 반환하며, 진행 중인 계산식은 Feedback으로 전달하도록 구성하였다.


5. Message, Service, Action 비교

세 가지 인터페이스는 데이터를 정의한다는 공통점이 있지만 구조가 다르다.

인터페이스구성사용 목적
.msg데이터Topic
.srvRequest + ResponseService
.actionGoal + Result + FeedbackAction

각 인터페이스는 다음과 같은 구조로 구성된다.

.msg

데이터
.srv

Request
---
Response
.action

Goal
---
Result
---
Feedback

따라서 .msg는 하나의 데이터를 전달하고, .srv는 요청과 응답을 주고받으며, .action은 목표와 결과뿐만 아니라 중간 Feedback까지 전달할 수 있도록 구성되어 있다.


6. package.xml 설정

작성한 인터페이스를 ROS 2에서 생성할 수 있도록 package.xml을 수정하였다.

cd ~/robot_ws/src/msg_srv_action_interface_example

nano package.xml

인터페이스 생성에 필요한 의존성을 다음과 같이 설정하였다.

<buildtool_depend>ament_cmake</buildtool_depend>
<buildtool_depend>rosidl_default_generators</buildtool_depend>

<exec_depend>builtin_interfaces</exec_depend>
<exec_depend>rosidl_default_runtime</exec_depend>

<member_of_group>rosidl_interface_packages</member_of_group>

rosidl_default_generators를 이용하여 인터페이스를 생성하고, rosidl_default_runtime을 통해 생성된 인터페이스를 사용할 수 있도록 설정하였다.


7. CMakeLists.txt 설정

다음으로 CMakeLists.txt를 수정하였다.

cd ~/robot_ws/src/msg_srv_action_interface_example

nano CMakeLists.txt

먼저 각각의 인터페이스 파일을 지정하였다.

set(msg_files
  "msg/ArithmeticArgument.msg"
)

set(srv_files
  "srv/ArithmeticOperator.srv"
)

set(action_files
  "action/ArithmeticChecker.action"
)

그리고 rosidl_generate_interfaces()를 이용하여 세 가지 인터페이스를 생성하도록 설정하였다.

rosidl_generate_interfaces(${PROJECT_NAME}
  ${msg_files}
  ${srv_files}
  ${action_files}
  DEPENDENCIES builtin_interfaces
)

마지막으로 생성된 인터페이스를 실행 환경에서 사용할 수 있도록 설정하였다.

ament_export_dependencies(rosidl_default_runtime)

8. 패키지 빌드

모든 파일의 작성을 완료한 후 워크스페이스에서 패키지를 빌드하였다.

cd ~/robot_ws

colcon build --symlink-install

처음 빌드했을 때 다음과 같은 오류가 발생하였다.

ModuleNotFoundError: No module named 'em'

오류 내용을 확인한 결과 ROS 2의 인터페이스 생성 과정에서 다음과 같이 Miniconda의 Python이 사용되고 있었다.

/home/namseungjoo/miniconda3/bin/python3

확인을 위해 Python 경로를 확인하였다.

which python3

처음에는 다음과 같이 출력되었다.

/home/namseungjoo/miniconda3/bin/python3

따라서 현재 활성화되어 있던 Conda 환경을 종료하였다.

conda deactivate

이후 다시 Python 경로를 확인하였고,

which python3

다음과 같이 시스템 Python을 사용하는 것을 확인하였다.

/usr/bin/python3

하지만 기존 빌드 과정에서 Miniconda Python 경로가 캐시에 남아 있었기 때문에 해당 패키지의 빌드 및 설치 디렉터리를 삭제하였다.

cd ~/robot_ws

rm -rf build/msg_srv_action_interface_example \
       install/msg_srv_action_interface_example

이후 해당 패키지만 다시 빌드하였다.

colcon build --symlink-install \
  --packages-select msg_srv_action_interface_example

이를 통해 인터페이스 패키지를 정상적으로 다시 빌드할 수 있었다.


9. 인터페이스 빌드 결과

빌드가 완료되면 작성한 .msg, .srv, .action 파일을 기반으로 ROS 2에서 사용할 수 있는 인터페이스가 생성된다.

생성된 인터페이스는 다음과 같은 설치 경로에서 확인할 수 있다.

~/robot_ws/install/msg_srv_action_interface_example

자료에서는 빌드 후 인터페이스에 대한 C/C++ 헤더 파일, Python 파일, IDL 파일 등이 생성되는 것을 설명하고 있다.

*.h
*.hpp
*.py
*.idl

이를 통해 직접 작성한 사용자 정의 인터페이스를 ROS 2 노드에서 사용할 수 있는 형태로 생성할 수 있다.


마무리

이번 실습에서는 ROS 2에서 사용하는 Topic, Service, Action 인터페이스의 구조와 차이점을 학습하였다.

msg_srv_action_interface_example 패키지를 생성하고 다음 세 가지 사용자 정의 인터페이스를 작성하였다.

ArithmeticArgument.msg
ArithmeticOperator.srv
ArithmeticChecker.action

또한 package.xml과 CMakeLists.txt를 수정하여 인터페이스 생성에 필요한 의존성과 빌드 설정을 구성하였다.

빌드 과정에서는 Miniconda Python이 ROS 2 인터페이스 생성 과정에 사용되면서 em 모듈을 찾지 못하는 문제가 발생하였다. 이후 Conda 환경을 종료하여 시스템 Python을 사용하도록 변경하고 기존 빌드 캐시를 삭제한 뒤 다시 빌드하여 문제를 해결하였다.

이번 실습을 통해 ROS 2에서 기존 인터페이스를 사용하는 것뿐만 아니라 필요한 데이터 구조에 맞춰 사용자 정의 Message, Service, Action 인터페이스를 직접 생성하는 방법을 익혔다.

또한 각 인터페이스의 구조와 차이점을 확인하고, package.xml과 CMakeLists.txt를 설정한 후 colcon build를 통해 인터페이스를 생성하는 전체 과정을 실습하였다.

0개의 댓글