인터페이스 패키지 설계

Hyuna·2024년 10월 18일
1

ROS2

목록 보기
4/15
post-thumbnail

📕 참고: ROS2로 시작하는 로봇 프로그래밍



인터페이스


인터페이스는 ROS2에서 노드 간 통신을 위해 사용되는 토픽,서비스,액션의 메시지 타입과 통신방법을 정의하는 것을 의미한다. 이러한 인터페이스는 별도의 패키지를 만들어 사용하는 것이 권장된다.
그 이유는 다음과 같다.

  • 재사용성 향상 : 특정노드에 종속되지 않고 여러 패키지에서 쉽게 참조 가능하고 코드의 중복을 방지한다.
  • 빌드 효율성 : 한 패키지의 설정이 변경되었을 때 전체 시스템을 빌드할 필요가 없이 독립적인 작업이 가능하다.
  • 의존성 관리 : 서로 다른 기능을 하는 노드들이 인터페이스만을 의존하여 의존성 트리가 단순해진다.
  • 개발과 테스트 분리 : 각 기능을 병렬 개발이 가능하므로 개발 속도를 높일 수 있다. 또한, 패키지 통합 전 모의테스트로 패키지를 개별 검증 할 수 있다.
개념설명예시
인터페이스시스템 간 데이터 교환 방식을 정의한 규약으로, 통신에 사용되는 데이터 구조를 정의example_interfaces/srv/AddTwoInts, sensor_msgs/msg/Image
타입데이터의 형태와 의미를 정의하며, 변수나 객체가 가질 수 있는 값의 종류를 지정int32, float64, string, geometry_msgs/msg/Point


이제 인터페이스 패키지를 생성헤보자.

패키지 생성


ros2 pkg create --build-type ament_cmake ros_study_msgs

생성한 패키지 안에 action,msg,srv 폴더를 만든다.

그리고 각 인터페이스를 정의하는데 필요한 파일을 폴더에 넣어준다.

✔ action/MyAction.action

액션 목표(Action Goal), 피드백(Action Feedback), 결과(Action Result)의 데이터 형식을 정의해준다.

✔ msg/MyMsg.msg

토픽에 사용될 메시지의 데이터 타입(정수형, 부동소수점, 문자열 등)을 정의해준다.

✔ srv/MySrv.srv

서비스의 요청(request)과 응답(response)의 데이터 형식을 정의해준다.



파일 수정

✔ package.xml

<buildtool_depend>rosidl_default_generators</buildtool_depend>
<exec_depend>builtin_interfaces</exec_depend>
<exec_depend>rosidl_default_runtime</exec_depend>

인터페이스 전용 패키지를 만들 때는 필수적으로 들어가야할 의존성 패키지이다.


✔ CMakeLists.txt

set(msg_files
    "msg/MyMsg.msg"
)

set(srv_files
    "srv/MySrv.svr"
)

set(action_files
    "action/MyAction.action"
)

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

set 명령어로 각 파일을 지정하고 rosidl_generate_interfaces에 해당하는 set들을 작성한다.



빌드

colcon build --packages-select ros_study_msgs 를 실행하여 빌드 결과를 확인한다.

ros2_ws/install/ros_study_msgs/include/ros_study_msgs/ros_study_msgs/에서 작성한 인터페이스를 사용하기 위한 파일들을 확인할 수 있다.

C에서 사용하는 *.c와 C++에서 사용하는 *.hpp 등을 확인할 수 있다.



실행 결과

새로운 패키지를 생성하여 msg interface를 테스트 해본다.

ros2 pkg create --build-type ament_python ros_study_py

✔ my_msg_test.py

ros_study_py 폴더에서 my_msg_test.py로 퍼블리셔 코드를 작성해주자. 그러면 MyMsg 라는 토픽을 생성하게 된다.


import rclpy
frm rlcpy.node import Node
from.ros_study_msgs.msg import MyMsg

class my_msg_test(Node):

    def __init__(self):
        super().__init__('my_msg_test') # 노드 이름: my_msg_test
        self.publisher_ = self.create_publisher(MyMsg, 'MyMsg', 10) 
        timer_period =0.5
        self.timer = self.create_timer(timer_period, self.timer_callback)
        self.i = 0.0
        
    def timer_callback(self):
        msg = MyMsg
        msg.num = self.i
        self.publisher_.publish(msg)
        self.get_logger().info(str(msg.num))
        self.i +=1
        
        
def main(args=None):
    rclpy.init(args=args)
    
    my_msg_test_publisher = my_msg_test() #클래스 인스턴스화
    
    rclpy.spin()
    my_msg_test_publisher.destroy_node()
    rclpy.shutdown()
    
        
if __name__ == '__main__':
    main()
    


✔ package.xml

<depend>ros_study_msgs</depend>
인터페이스 패키지에 대한 의존성을 추가한다.


✔ setup.py

my_msg_test = ros_study_py.my_msg_test:main
콘솔 스크립트에 명령어를 추가한다.



터미널1에 ros2 run ros_study_py my_msg_test 를 실행한다.

my_msg_test 에서 토픽이 발행된 것을 확인할 수 있다.



터미널2에서 ros2 topic list로 현재 발행되고 있는 토픽 리스트를 확인할 수 있다.

이후, ros2 topic echo /MyMsgMyMsg로 발행되는 메시지를 터미널에 출력하게 하였다.

0개의 댓글