본문 바로가기

FOSCAR-(Autonomous Driving)/ROS 스터디

[2023 ROS 스터디] 조성준 #3주차 - ROS 기본 프로그래밍

반응형

 오늘의 과제는 ROS Courses 7강. ROS 기본 프로그래밍을 듣고, 공부하는 것이다. 이번 수업부터는 실습을 중점으로 공부하게 될 것 같다. 힘차게 시작하자.

 

Chapter 7. ROS 기본 프로그래밍

이번 강의는 1. ROS 프로그래밍 전에 알아둬야 할 것 2. 퍼블리셔, 서브스크라이버 노드의 작성 및 실행 3. 서비스 서버와 클라이언트 노드의 작성 및 실행 4. 액션 서버와 클라이언트 노드 작성 및 실행 5. 파라미터 사용법 6. Roslaunch 사용법의 순서대로 진행되며, 실습위주의 수업이 될 것 같다.

 

ROS의 표준단위

 ros는 목적인 글로벌화를 위해 단위를 통일하기로 했는데, 표준단위로는 SI(국제단위계)를 사용한다.

Quantity Unit
angle radian
frequency hertz
force newton
power watt
voltage volt
length meter
mass kilogram
time second
current ampere
temperature celsius

 

좌표 표현 방식

 ●  x : 앞 y : 왼쪽 z : 위 

 ●  회전방향은 오른손 법칙을 따른다. ( 정회전 : 시계 반대 방향 , 역회전 : 시계 방향)

 

프로그래밍 규칙

 ● 패키지, 토픽, 파일, 네임스페이스 명명 규칙을 따라야 한다.

 

이외의 것들은 ROS WIKI에 가면 확인할 수 있다.

당장에는 이런 규칙들이 중요하지는 않지만, 이후 공식패키지를 사용하거나, 만들어서 올릴 때는 당연히 준수해야 하는 규칙들이다.

 

roscd 패키지명 : cd는 패키지의 주소를 적어줘야 하는 반면 roscd는 패키지가 있는 장소로 이동한다. 

 

Topic 실습

Topic : 단방향의 통신이며, 연속적인 통신이다. 보내는 쪽을 퍼블리셔 받는 쪽은 서브스크라이버다

 

1) 패키지 생성

catkin_create_pkg : 자동으로 패키지에서 꼭 필요한 파일, 폴더를 만들어 주는 명령어로 $catkin_create_pkg 패키지명 (패키지가 의존하는 패키지) 만약 의존 패키지에 추가해주지 않으면, 후에 package.xml에 직접 넣어줘야 한다.

cd ~/catkin_ws/src
catkin_create_pkg ros_tutorials_topic message_generation std_msgs ros cpp

● catkin_ws로 이동 후 ros_tutorials_topic이라는 패키지를 만드는데, std_msgs(bool, char, int 등 기본적으로 사용되는 자료형이 들어있다.)와 roscpp(c++)는 이 패키지에서 사용할 패키지를 의미한다. 

● 패키지를 만들면 자동으로 include(헤더 파일 폴더), src(소스 코드 폴더), CMakeLists.txt(빌드 설정 파일), package.xml(패키지 설정 파일) 이 생성된다.

 

2) 패키지 설정 파일의 수정

package.xml 파일은 패키지의 정보를 담은 XML 파일로 버전, 패키지 이름, 저작자, 라이센스 등이 적혀있는 문서이다. 만일 자신이 만든 패키지를 배포할 예정이라면 꼼꼼히 적어야 한다.

 

3) 빌드 설정 파일 (CMakeLists.txt) 수정

빌드 옵션, 빌드 관련 정보들을 CMakeLists.txt에 작성되어 있다. 패키지명, 의존 패키지, 만드는 메시지 명 등이 적혀있다. 빌드시 사용하는 파일이다.

 

4) 메시지 파일 작성

ROS message를 필드 유형과 필드 이름이 기술된 간단한 텍스트파일이다. 다른 언어들의 소스코드들을 실행시키는 데 사용된다.

 

5, 6) 퍼블리셔 노드 작성 & 서브스크라이버 노드 작성

● ros/ros.h : 기본적인 ros의 헤더

● ros::init() : 노드명의 초기화

● ros::NodeHandle nh; : ROS 시스템과의 통신을 위한 노드 핸들

● Time::now() : 현재 시간 가져오기

● ROS_INFO() : prinf의 역할 ros에서는 로봇의 메시지를 그 용도에 따라 다르게 뜯어볼 수 있게 하기 위해 구분한다.

 

7) ROS 노드 빌드

catkin_make를 통해 빌드를 발행한다. 빌드된 결과물은 /catkin_ws의 /bulid와 /devel 폴더에 각각 생성한다.

● /build 폴더에는 케킨 빌드에서 사용된 설정 내용이 저장

● /devel/lib/ros_tutorials_topic 폴더에는 실행파일이 저장

● /devel/include/ros_tutorials_topic 폴더에는 메시지 파일로부터 자동  생성된 메시지 헤더 파일이 저장

 

8) 퍼블리셔 실행

노드 실행 전 roscore 실행하기 → rosrun ros_tutorials_topic topic_publisher

 

9) 서브스크라이버 실행

rosrun ros_tutorials_topic topic_subscriber

 

10) 실행된 노드들의 통신 상태 확인 

rqt_graph를 통해 확인할 수 있다.

rqt graph와 뒤에 실행되고 있는 것들을 보면 알 수 있듯 연속적이며, 단방향의 통신이 이뤄지고 있다.

 

Service 실습

Service : 양방향의 통신이며, 일회성의 통신이다. 요청하는 쪽을 서비스 클라이언트 응답하는 쪽을 서비스 서버라고 한다.

실습과정은 Topic과 거의 다를게 없다.

1. 패키지 생성

2. 패키지 설정 파일(package.xml) 수정

3. 빌드 설정 파일(CMakeLists.txt) 수정

4. 서비스 파일 작성

5. 서비스 서버 노드 작성

6. 서비스 클라이언트 노드 작성

7. ROS 노드 빌드

8. 서비스 서버 실행

9. 서비스 클라이언트 실행

서비스는 일회성이기에 rqt_graph로 확인할 수 없다.

[플러그인(Plugins)] → [서비스(Service)] → [Service Caller] 

service의 경우 일회성인 통신이기에 rqt graph를 통해서 노드간의 연결을 확인할 수 없다. Service Caller를 통해 확인할 수 있다.

 

비록 선언은 퍼블리셔 혹은 서브스크라이버로 했지만, 꼭 그렇게 사용해야 하는 것은 아니다. 하나의 노드는 복수의 퍼블리셔, 서브스크라이버도 가능하다. 하나의 노드에서 다양한 역할을 수행할 수 있다.

 

Parameter 실습

Parameter(매개변수) : 유저가 정해 놓은 파라미터를 저장하고 있고, 명령을 통해 변경, 사용이 가능하다. 글로벌 변수, 글로벌 파라미터라고 생각하면 편하다. 소스의 빌드나 변경 없이 사용이 가능하다.

1) 파라미터를 활용한 노드 작성

앞서 실습한 service_server.cpp 소스를 수정해서 사용하자. 

#define PLUS           1
#define Minus          2
#define MULTIPLICATION 3
#define DIVISION       4

각 연산이름을 숫자로 정의하고, switch 구문을 이용해 기능을 구현해 준다. 

●  setParam() : 매개변수의 초기 설정

●  getParam() : 매개변수를 읽어 온다.

 

2. 노드 빌드 및 발행

 

3. 매개변수 목록 보기

● rosparam list 명령어로 현재 사용된 파라미터의 목록을 확인할 수 있다.

 

4. 파라미터 사용

기본설정된 1번 덧셈이 아닌 파라미터를 2번으로 변경하니 뺄셈을 실행하는 모습이다.

 

roslaunch 실습

● roslaunch는 하나 이상의 정해진 노드를 실행할 수 있다. 이름, 패키지명 등의 환경설정을 할 수 있다. 

● roslaunch는 *. launch라는 파일을 사용해 실행 노드를 설정한다. XML 기반이며, 태그별 옵션을 제공한다.

● roslaunch [패키지명] [roslaunch 파일]

 

roslaunch의 활용

●<launch> 태그 안에는 roslaunch 명령어로 노드를 실행할 때 필요한 태그들이 기술된다.

●<node> roslaunch로 실행할 노드를 기술하게 된다.

  → pkg : 패키지의 이름, type : 실제 실행할 노드의 이름(노드명), name : 일반적으로 type과 같게 설정하지만, 팔요 시 이                 름을 변경할 수 있다

이전의 작성한 topic_publisher와 topic_subscriber 노드의 이름을 바꾸어 실행하자. 퍼블리셔 노드와 서브스크라이버 노드를 두 개씩 구동하여 서로 별도의 메시지 통신을 해보자. 

이름을 바꾸어서 실행하는 것은 성공했지만, 1 : 1 통신이 아닌 1: N 통신을 진행하고 있다.

1 : 1 통신을 하기 위해서는 통신하게 하고 싶은 노드끼리 묶어주면 된다. <group>을 이용해 묶어주고 결과를 보자

그룹을 통해 묶어주고 나니 묶인 그룹대로 1 : 1 통신을 하는 모습이다.

 

이상으로 이번 주차 과제를 마치겠습니다. 다들 파이팅~

반응형