본문 바로가기

FOSCAR-(Autonomous Driving)/ROS 스터디

[2024 ROS 스터디] 손희문 #3주차 - ROS 기본 프로그래밍

반응형

7강 목차

- Publisher, Subscriber 노드 작성

- Service, Client 노드 작성

- Roslaunch 실행

 

Roscore를 실행시키면 3가지의 기능을 한다고 요약할 수 있다.

1. rosmaster 기능 (노드 관련 기능, 노드들의 통신 연결)

2. rosout (로그 기록)

3. parameter 서버를 구동 (각종 파라미터를 기록)

 

각종 노드를 작성하기 전에 ROS에서 사용하는 메시지들의 표준 단위에 대해 알아야 한다.

 

좌표 표현방식의 경우 오른손 법칙을 사용하고

표준단위는 SI단위를 사용해서 주의해야 할 부분은 각도를 라디안으로 표현한다는 점 정도이다.

프로그래밍 규칙에 나오는 명명규칙의 경우는 혼자만 개발하고 혼자만 사용한다면 마음대로 사용해도 문제가 없겠지만,

공동작업을 하는 경우가 많을 것이므로 ROS Wiki에서 권장하는 방식에 익숙해지도록 연습하자.

 

http://wiki.ros.org/ROS/Patterns/Conventions

 

ROS/Patterns/Conventions - ROS Wiki

Standard Units of Measure and Coordinate Systems Standard units and coordinate conventions for use in ROS have been formalized in REP-0103. Naming ROS Resources Names play an important role in ROS and following naming conventions simplifies the process of

wiki.ros.org

해당 링크에 들어가면

1. Standard Units of Measure and Coordinate Systems 부분에 단위계, 좌표계 관련 내용을 확인 할 수 있다.

2. Naming ROS Resources 에서 패키지, 토픽, 서비스, 메시지, 노드 관련 권장되는 명명법을 확인할 수 있다.

추가적으로 ROS/ Patterns/ Conventions/ Workspaces의 REP-0128 문서를 살펴보면 Catkin-based 워크스페이스의 naming convention에 대한 설명도 나와있다.

 

ROS메시지 통신의 종류

1. 토픽 : 퍼블리셔노드에서 토픽을 발행해서 서브스크라이버 노드에서 받는 형태인 [단방향 통신, 연속성 가짐]

2. 서비스 : 클라이언트 노드가 서비스 요청, 이를 받은 서비스 서버가 프로세스 실행 후 결과를 클라이언트 노드로 전달

클라이언트 노드는 서비스 요청이 있을 때까지 대기 상태 [양방향 통신, 1회성]

3. 액션 : 서비스와 비슷하지만 추가적으로 액션 피드백을 전달한다는 점에서 차이가 있다. [중간 결과물 피드백]

 

 

본격적으로 퍼블리셔와 서브스크라이버 노드 작성을 해보자

워크스페이스 생성과 패키지 생성은 강의를 그대로 따라가면 되므로 생략하고 간단히 개념정도만 정리하고 넘어가겠다.

 

1. include폴더 = 헤더파일 폴더

2. src폴더 = 소스 코드 폴더 (파이썬파일은 scripts 폴더를 따로 만들어서 관리하는 경우도 봤다)

3. CMakeLists.txt = 빌드 설정 파일 > 소스코드 작성 후 실행파일 만들 때 사용되는 옵션들

4. package.xml = 패키지 설정 파일 > 패키지명, 저작자 라이센스, 의존성 패키지 등 기술

 

그 다음으로 topic_publisher.cpp 의 구조와 topic_subscriber.cpp 의 구조를 보고 넘어가자.

 

 

강의에서 CMakeLists에서 메시지를 새로 선언을 해버렸기에 메시지 파일 헤더를 include하는 줄이 들어있는 것을 확인할 수 있다.

MsgTutorial.msg에서 time stamp와 int32 data를 추가했기에 14, 15번 줄에서 stamp와 data를 사용하는 것을 볼 수 있다.

 

 

서브스크라이버 노드에서는 콜백함수 관련 설정이 중요하다. void msgCallback함수 선언을 통해 MsgTutorial 메시지를 받는 것을 확인할 수 있다. 서브스크라이버 노드에서 spin()설정은 지속적인 동작을 위한 필수 설정이다. 아래 간단한 spin()함수에 대한 간단한 설명을 추가한다.

 

spin() 함수를 호출하면 ROS 노드는 메시지를 수신하고 해당 메시지에 대한 등록된 콜백 함수를 실행합니다. spin()은 ROS의 이벤트 루프를 시작하며, 이벤트 루프는 노드가 메시지를 받을 때마다 등록된 콜백 함수를 실행하여 메시지를 처리합니다.

 

roscore를 먼저 실행하고, 각 터미널에 사용하는 쉘에 따라 source devel/setup.bash 또는 source devel/setup.zsh를 입력하고 두 개의 노드를 실행시키자

 

다음은 서비스 서버와 서비스 클라이언트 노드의 작성이다.

서비스는 토픽과 달리 일회성 메시지 통신이기에 서비스의 요청과 응답이 완료되면 연결된 두 노드는 접속이 끊긴다.

이러한 서비스는 로봇에 특정 동작을 수행하도록 요청할 때에 명령어로써 많이 사용된다고 한다.

강의에서 작성한 코드는 클라이언트를 실행하면서 입력한 매개변수 2개를 서비스 서버가 그 둘의 합을 응답으로 전송하는 동작을 한다.

 

service_server.cpp 소스를 수정해서 두 매개변수의 덧셈뿐만 아니라, 사칙연산을 할 수 있도록 파라미터를 활용해 보자.

 

switch, case문을 활용해 사용자의 연산자 입력에 따라 res가 변한다. 36번째줄에서 초기화가 되고, 42번째 줄에서 입력한 연산자에 맞게 파라미터가 변경된다. calculation_method를 사용했기에 catkin_make이후 rosparam list를 입력하면 /caculation_method가 나오는 것을 확인할 수 있을 것이다.

 

rogg

result 5로 변경된 부분이 잘렸는데 위쪽 터미널에서 [5]로 출력된 것을 보면 rosparam set 을 통해 파라미터 변경이 잘 이루어졌음을 확인할 수 있다.

 

 

마지막으로 launch파일 작성이다. roslaunch 를 통해 하나 이상의 정해진 노드를 실행할 수 있다.

실행 명령어 roslaunch [패키지명] [roslaunch 파일]

<node pkg = 패키지명, type = 실제 실행할 노드 이름, name = type에 해당하는 노드가 실행될 때 붙여지는 실행명. 일반적으로 name= type이지만 필요에 따라 변경가능 >

 

 

오른쪽과 같이 런치파일을 설정할 경우 조금 이상한 형태가 나온다. publisher노드에서 두개의 subscriber모두에게 토픽을 전송하고 있는 모습이다.  사용되는 메시지의 이름을 바꾸어지지 않은 것이 그 원인이다.

이를 해결하기 위해 왼쪽과 같이 namespace태그 설정을 해주자.

 

 

launch 태그

<group> 실행되는 노드를 그룹화 할 때 사용

<arg> launch 파일 내에 변수를 정의할 수 있어서 실행시킬 때 매개변수 변경 가능!

<param> 매개변수 이름, type, value를 설정한다.

<include> 다른 패키지나 같은 패키지에 속해 있는 다른 launch 를 불러와 하나의 launch 파일처럼 실행가능

반응형