# 3장 ROS 구조 및 빌드 시스템

### 1. ROS 용어

* 패키지 : ROS 소프트웨어의 기본 단위. 패키지는 노드, 라이브러리, 환경설정 파일들을 통합하는 최소의 빌드 단위이며, 배포 단위이다.
* 패키지 매니페스트 : 패키지의 작성자, 라이선스, 의존성, 컨피그레이션 플레그 등을 포함하는 패키지 정보
* 메타 패키지 : 이전에는 스택으로 불리웠지만, 특수한 목적을 위한 패키지 그룹을 지칭한다. 대표적인 예로 네비게이션 스택을 예로 들 수 있다.
* 메시지 : 한 ROS 프로세서에서 다른 ROS 프로세서로 정보를 전달하는 한 형태

![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-DMBXpEHRzz/0a7779b671b249ae0488b6a0f06fedd9d661c0205cb6b7706ddd69535904b0f35728babb602a9e00f32dda6084ff853fd2b200aafd368eabf2f14f8b9935040f66311be1ddccf08c22a626085f79d687ecdaf93c5adf42947b6267e88bee5169401f436d)

* 서비스 : 프로세스간의 요청/응답 상호작용
* Service, Service Server, Service Client

![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-42xSFDZjS4/6d9efc8777cce7fce8ab9185f93a55644e34c4ba2e86ad5613261e0c4511cac6b86fe4bbefe3d09821032060ca12083f62ac371acb90fdc861d39db3f7be94a1967aa13493633ad6358430a198182e4ec0793f7da9142f0368c622cd696f289f202ea3f7)

* Node : 최소 단위의 실행 가능한 프로세서를 가리키는 용어로써 하나의 실행 가능한 프로그램으로 생각하면 된다. ROS에서는 최소한의 실행 단위로 프로그램을 나누어 작업하게 된다. 각 노드는 메시지 통신으로 데이터를 주고 받는다.
* Package : 하나 이상의 노드, 노드 실행을 위한 정보 등을 묶어 놓은것. 또한, 패키지의 묶음을  메타패키지라 하여 따로 분리 한다.
* Message : 메시지를 통해 노드 간의 데이터를 주고 받게 된다. 메시지는 integer, floating point, boolean와 같은 변수 형태이다. 또한, 메시지 안에 메시지를 품고 있는 간단한 데이터 구조 및 메시지들의 배열과 같은 구조도 사용할 수 있다.
* Publisher, Subscriber, Topic

![](https://917233451-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LcW4PzQzrJVLjrT8lUh%2F-MNBQpKGmXCfslqzaQMe%2F-MNC6_ftU4n-qqFNp1ic%2FConceptual-model-of-ROS-topics-presented-by-Radu-Rusu-in-his-tutorial8.png?alt=media\&token=a0de4716-9958-4d74-947c-120c78f88507)

* Action, Action Server, Action Client

![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-1Jtr7XV5Lf/64c152c99865c9375c806ccfd21bffd9df8ebc861047b37072ac63cf77e2e39c7520450cb64b07da1188a29e78dc572366951506004e1ab84e6f9c24c511fd1bb3ec1ab56b83d056c9749c529c790e292f0aa7cb1029a9ad6fbafdcc743f0eb2c73ffad2)

### 2. ROS 통신 방식

![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-oCeYSrEjnZ/dbabe085ea022d9882d4d63d9a866641eb023bab202275b25198151d4b8cbb5cb4e605c8ac0aa3e173c44fd288da4bb28a155ff17e60cbece9664f77c2dc9ade078a464577ae2835bae82546665f9d977d9ced2842b3064d7dd15d4fcf48dab613c7ca57)

\ <br>

![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-h61bWf86AK/9e04beefe5043b0803395137b8f889ca48859466d9371628150687f1a85ee513b04d305f465b673a0c6d05c8b5784e6b7acbedd93764dc38e326c91c99d2c2a8e8ef3b9f3a369f2f4f7cbe4ab069977b8f2723ec2d16de0ef5d1dfa8707cd7e207297c5f)

### 3. TF(Transform)

* 각조인트(joint)들의 상대좌표 변환
* 트리(tree) 형태로 조인트들 간의 관계도를 표시함

![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-1IjoerM6_D/c9feb20391fc83454f31deb9a5e6ee40d95e5123c12cd9b131d6eb5e3b8f0f03bda3098c96167f99a4b90fcaca4ac26a711d3ed75aba818151843f3ff4c5c093775779a043669cf6b121d2e4c31e73e1ff41c754f8d10bd85ea37ef84a1bd9673c9e324f)

### 4. ROS 관련 명령어

|       |     |                           |                       |
| ----- | --- | ------------------------- | --------------------- |
| 명령어   | 중요도 | 명령어풀이                     | 세부설명                  |
| roscd | ★★★ | ros+cd(changes directory) | 지정한 ROS 패키지의 디렉터리로 이동 |
| rosls | ★☆☆ | ros+ls(lists files)       | ROS 패키지의 파일목록 확인      |
| rosed | ★☆☆ | ros+ed(editor)            | ROS 패키지의 파일편집         |
| roscp | ★☆☆ | ros+cp(copies files)      | ROS 패키지의 파일복사         |
| rospd | ☆☆☆ | ros+pushd                 | ROS 디렉터리 인덱스에 디렉터리 추가 |
| rosd  | ☆☆☆ | ros+directory             | ROS 디렉터리 인덱스 확인       |

|           |     |            |                                                            |
| --------- | --- | ---------- | ---------------------------------------------------------- |
| 명령어       | 중요도 | 명령어풀이      | 세부설명                                                       |
| roscore   | ★★★ | ros+core   | -master(ROS 네임서비스) -rosout(로그기록) -parameter server(파라미터관리) |
| rosrun    | ★★★ | ros+run    | 노드실행                                                       |
| roslaunch | ★★★ | ros+launch | 노드를 여러개 실행 및 실행 옵션 설정                                      |
| rosclean  | ★★☆ | ros+clean  | ROS 로그 파일을 검사하거나 삭제                                        |

|            |     |                      |                           |
| ---------- | --- | -------------------- | ------------------------- |
| 명령어        | 중요도 | 명령어풀이                | 세부설명                      |
| rostopic   | ★★★ | ros+topic            | ROS 토픽 정보 확인              |
| rosservice | ★★★ | ros+service          | ROS 서비스 정보 확인             |
| rosnode    | ★★★ | ros+node             | ROS 노드 정보 확인              |
| rosparam   | ★★★ | ros+param(parameter) | ROS 파라미터 정보 확인, 수정        |
| rosbag     | ★★★ | ros+bag              | ROS 메시지 기록, 재생            |
| rosmsg     | ★★☆ | ros+msg              | ROS 메시지 정보 확인             |
| rossrv     | ★★☆ | ros+srv              | ROS 서비스 정보 확인             |
| rosversion | ★☆☆ | ros+version          | ROS 패키지 및 배포 릴리즈 버전 정보 확인 |
| roswtf     | ☆☆☆ | ros+wtf              | ROS 시스템 검사                |

|                             |     |                                          |
| --------------------------- | --- | ---------------------------------------- |
| 명령어                         | 중요도 | 세부설명                                     |
| catkin\_create\_pkg         | ★★★ | 패키지 자동 생성                                |
| catkin\_make                | ★★★ | 캐킨 빌드시스템에 기반을 둔 빌드                       |
| catkin\_eclipse             | ★★☆ | 캐킨 빌드 시스템으로 생성한 패키지를 이클립스에서 사용 할 수 있게 변경 |
| catkin\_prepare\_release    | ★★☆ | 릴리즈 할때 사용되는 로그정리 및 버전 태깅                 |
| catkin\_generate\_changelog | ★★☆ | 릴리즈 할때 CHANGELOG.rst 파일 생성 또는 업데이트       |
| catkin\_init\_workspace     | ★★☆ | 캐킨 빌드 시스템의 작업폴더 초기화                      |
| catkin\_find                | ★☆☆ | 캐킨 검색                                    |

|               |     |                    |                                 |
| ------------- | --- | ------------------ | ------------------------------- |
| 명령어           | 중요도 | 명령어풀이              | 세부설명                            |
| rospack       | ★★★ | ros+pack(age)      | ROS 패키지와 관련된 정보 보기              |
| rosinstall    | ★★☆ | ros+install        | ROS 추가 패키지 설치                   |
| rosdep        | ★★☆ | ros+dep(endencies) | 해당패키지의 의존성 파일 설치                |
| roslocate     | ☆☆☆ | ros+locate         | ROS 패키지 정보 관련 명령어               |
| roscreate-pkg | ☆☆☆ | ros+create-pkg     | ROS 패키지 자동생성(구rosbuild 시스템에서사용) |
| rosmake       | ☆☆☆ | ros+make           | ROS 패키지를 빌드(구rosbuild 시스템에서사용)  |

### 5. 빌드 시스템

|             |          |
| ----------- | -------- |
| Column 1    | Column 2 |
| Quantity    | Unit     |
| angle       | radian   |
| frequency   | hertz    |
| force       | newton   |
| power       | watt     |
| voltage     | volt     |
| length      | meter    |
| mess        | kilogram |
| time        | second   |
| current     | ampere   |
| temperature | celsius  |

|         |               |                                               |
| ------- | ------------- | --------------------------------------------- |
| 대상      | 명명규칙          | 예제                                            |
| 패키지     | under\_scored | Ex) first\_ros\_package                       |
| 토픽, 서비스 | under\_scored | Ex) raw\_image                                |
| 파일      | under\_scored | Ex) turtlebot3\_fake.cpp                      |
| 네임스페이스  | under\_scored | Ex) ros\_awesome\_package                     |
| 변수      | under\_scored | Ex) string table\_name;                       |
| 타입      | CamelCased    | Ex) typedefint32\_t propertiesNumber;         |
| 클래스     | CamelCased    | Ex) classUrlTable                             |
| 구조체     | CamelCased    | Ex) structUrlTableProperties                  |
| 열거형     | CamelCased    | Ex) enumChoiceNumber                          |
| 함수      | camelCased    | Ex) addTableEntry();                          |
| 메소드     | camelCased    | Ex) void setNumEntries(int32\_t num\_entries) |
| 상수      | ALL\_CAPITALS | Ex) const uint8\_t DAYS\_IN\_A\_WEEK = 7;     |

\
\
SI(Systeme Internationale) 단위 사용\ <br>

![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-9n5KCYjUCZ/4a5bd0013714cef7bb232c5984c09031a25c01144449a5f5418f6f2256a1b72b83e496b982ce903dce5a99c52e99dc74296e02eb5dcb514e85181bd01b24290fa58ff4f3a013f27fcbe5884806ea7fe29c064df882e93d49384703e59dfcfcb404dc9cb6)

### **5.1 Topic / Publisher / Subscriber 실습**

**1) 패키지 생성**

```
cd ~/catkin_ws/src
```

```
catkin_create_pkg ros_tutorials_topic message_generation std_msgs roscpp
```

```
cd ros_tutorials_topic
```

```
ls
```

```
include → 헤더파일폴더
src→ 소스코드폴더
CMakeLists.txt → 빌드설정파일
package.xml→ 패키지설정파일
```

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

```
gedit package.xml
```

```
<?xmlversion="1.0"?>
<packageformat="2">
<name>ros_tutorials_topic</name>
<version>0.1.0</version>
<description>ROS turtorialpackage to learn the topic</description>
<license>Apache 2.0</license>
<authoremail="pyo@robotis.com">Yoonseok Pyo</author>
<maintaineremail="pyo@robotis.com">Yoonseok Pyo</maintainer>
<urltype="website">http://www.robotis.com</url>
<urltype="repository">https://github.com/ROBOTIS-GIT/ros_tutorials.git</url>
<urltype="bugtracker">https://github.com/ROBOTIS-GIT/ros_tutorials/issues</url>
<buildtool_depend>catkin</buildtool_depend>
<depend>roscpp</depend>
<depend>std_msgs</depend>
<depend>message_generation</depend>
<export></export >
</package> 
```

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

```
gedit CMakeLists.txt
```

```
cmake_minimum_required(VERSION 2.8.3) 
project(ros_tutorials_topic) 
## 캐킨빌드를할때요구되는구성요소패키지이다.
## 의존성패키지로message_generation, std_msgs, roscpp이며이패키지들이존재하지않으면빌드도중에에러가난다.
find_package(catkin REQUIRED COMPONENTS message_generationstd_msgsroscpp)
## 메시지선언: MsgTutorial.msg 
add_message_files(FILES MsgTutorial.msg)
## 의존하는메시지를설정하는옵션이다.
## std_msgs가설치되어있지않다면빌드도중에에러가난다.
generate_messages(DEPENDENCIES std_msgs)
## 캐킨패키지옵션으로라이브러리, 캐킨빌드의존성, 시스템의존패키지를기술한다. 
catkin_package( 
LIBRARIES ros_tutorials_topic
CATKIN_DEPENDS std_msgsroscpp
)

## 인클루드디렉터리를설정한다.
include_directories(${catkin_INCLUDE_DIRS})
## topic_publisher노드에대한빌드옵션이다. 
## 실행파일, 타깃링크라이브러리, 추가의존성등을설정한다.
add_executable(topic_publisher src/topic_publisher.cpp)
add_dependencies(topic_publisher ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(topic_publisher ${catkin_LIBRARIES})
## topic_subscriber노드에대한빌드옵션이다. 
add_executable(topic_subscriber src/topic_subscriber.cpp)
add_dependencies(topic_subscriber ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(topic_subscriber ${catkin_LIBRARIES})
```

\
**4) 메시지 파일 작성**

```
roscd ros_tutorials_topic
```

```
mkdir msg
```

```
cd msg
```

```
gedit MsgTutorial.msg
```

```
time stamp
int32 data
```

\
**5) 퍼블리셔 노드 작성**

```
roscd ros_tutorials_topic/src
```

```
gedit topic_publisher.cpp
```

```
#include "ros/ros.h"// ROS 기본 헤더 파일
#include "ros_tutorials_topic/MsgTutorial.h"// MsgTutorial 메시지 파일 헤더(빌드 후 자동 생성 됨)
int main(int argc, char **argv) // 노드 메인 함수
{
ros::init(argc, argv, "topic_publisher"); // 노드명 초기화
ros::NodeHandle nh;// ROS 시스템과 통신을 위한 노드 핸들 선언
// 퍼블리셔선언, ros_tutorials_topic패키지의MsgTutorial메시지파일을이용한
// 퍼블리셔ros_tutorial_pub를작성한다. 토픽명은"ros_tutorial_msg" 이며,
// 퍼블리셔큐(queue) 사이즈를100개로설정한다는것이다
ros::Publisher ros_tutorial_pub= nh.advertise<ros_tutorials_topic::MsgTutorial>("ros_tutorial_msg", 100);
// 루프주기를설정한다. "10" 이라는것은10Hz를말하는것으로0.1초간격으로반복된다
ros::Rate loop_rate(10);
// MsgTutorial메시지파일형식으로msg라는메시지를선언
ros_tutorials_topic::MsgTutorial msg;
// 메시지에사용될변수선언

int count = 0;

while (ros::ok())
{
msg.stamp= ros::Time::now();// 현재시간을msg의하위stamp 메시지에담는다
msg.data= count; // count라는변수값을msg의하위data 메시지에담는다
ROS_INFO("send msg= %d", msg.stamp.sec); // stamp.sec메시지를표시한다
ROS_INFO("send msg= %d", msg.stamp.nsec); // stamp.nsec메시지를표시한다
ROS_INFO("send msg= %d", msg.data); // data 메시지를표시한다
ros_tutorial_pub.publish(msg);// 메시지를발행한다
loop_rate.sleep();// 위에서정한루프주기에따라슬립에들어간다
++count;// count 변수1씩증가
}

return 0;
}
```

\
**6) 서브 스크라이버 노드 작성**<br>

```
roscd ros_tutorials_topic/src→ 패키지의 소스 폴더인 src폴더로 이동
```

```
gedit topic_subscriber.cpp→ 소스파일 신규작성 및 내용 수정
```

```
#include "ros/ros.h" // ROS 기본헤더파일
#include "ros_tutorials_topic/MsgTutorial.h" // MsgTutorial메시지파일헤더(빌드후자동생성됨)
// 메시지콜백함수로써, 밑에서설정한ros_tutorial_msg라는이름의토픽
// 메시지를수신하였을때동작하는함수이다
// 입력메시지로는ros_tutorials_topic패키지의MsgTutorial메시지를받도록되어있다

void msgCallback(const ros_tutorials_topic::MsgTutorial::ConstPtr& msg)
{
ROS_INFO("recievemsg= %d", msg->stamp.sec); // stamp.sec메시지를표시한다
ROS_INFO("recievemsg= %d", msg->stamp.nsec); // stamp.nsec메시지를표시한다
ROS_INFO("recievemsg= %d", msg->data); // data 메시지를표시한다
}

int main(int argc, char **argv)// 노드메인함수
{
ros::init(argc, argv, "topic_subscriber");// 노드명초기화
ros::NodeHandle nh; // ROS 시스템과통신을위한노드핸들선언
// 서브스크라이버선언, ros_tutorials_topic패키지의MsgTutorial메시지파일을이용한
// 서브스크라이버ros_tutorial_sub를작성한다. 토픽명은"ros_tutorial_msg" 이며,
// 서브스크라이버큐(queue) 사이즈를100개로설정한다는것이다
ros::Subscriber ros_tutorial_sub= nh.subscribe("ros_tutorial_msg", 100, msgCallback);
// 콜백함수호출을위한함수로써, 메시지가수신되기를대기, 
// 수신되었을경우콜백함수를실행한다
ros::spin();

return 0;
}
```

\
**7) ROS 노드 빌드**

```
cd~/catkin_ws
```

```
catkin_make
```

\
\&#xNAN;**•ros\_tutorials\_topic 패키지의 소스 코드 파일: \~/catkin\_ws/src/ros\_tutorials\_topic/src**

**•ros\_tutorials\_topic패키지의 메시지 파일: \~/catkin\_ws/src/ros\_tutorials\_topic/msg**

**•빌드된 결과물은 /catkin\_ws의 /build와/devel폴더에 각각 생성**

**•/build 폴더에는 캐킨 빌드에서 사용된 설정 내용이 저장**

**•/devel/lib/ros\_tutorials\_topic폴더에는 실행 파일이 저장**

**•/devel/include/ros\_tutorials\_topic폴더에는 메시지 파일로 부터 자동 생성된 메시지 헤더 파일이 저장**<br>

```
roscore
```

```
rosrun ros_tutorials_topic topic_publisher
```

```
rostopic list
```

```
/ros_tutorial_msg
/rosout
/rosout_agg
```

```
rostopic echo /ros_tutorial_msg
```

```
rosrun ros_tutorials_topic topic_subscriber
```

```
rqt_graph
```

![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-mSnsPJRh-h/d2927bca138467059c54359743842b88f46de591aa877cbb460471522816090dc9b77c042c24349bb466a25edd589ed9f907c91b2a221ddec9dc50a0a0b896f98728c6a4629f0211e352c9a632f3f022c75b4aefa2796af183e123f30f557ffb44d57ad9)

### **5.2 git을 활용하여 예제 활용하기**

```
sudo apt-get install git
```

```
cd~/catkin_ws/src
```

```
git clone https://github.com/ROBOTIS-GIT/ros_tutorials.git
```

```
cd~/catkin_ws
```

```
catkin_make
```

```
rosrun ros_tutorials_topic topic_publisher
```

```
rosrun ros_tutorials_topic topic_subscriber
```

### &#x20; 5.3 roslaunch

\
~~`•roslaunch는 하나 이상의 정해진 노드를 실행 시킬수 있다.`~~

~~`•roslaunch는‘*.launch’라는 파일을 사용하여 실행노드를 설정하는데 이는XML 기반이며, 태그별 옵션을 제공한다.`~~

~~`•실행 명령어는"roslaunch [패키지명] [roslaunch파일]”이다.`~~<br>

```
roscd ros_tutorials_topic
```

```
mkdir launch
```

```
cd launch
```

```
gedit union.launch
```

```
<launch>
<node pkg="ros_tutorials_topic" type="topic_publisher" name="topic_publisher1"/>
<node pkg="ros_tutorials_topic" type="topic_subscriber" name="topic_subscriber1"/>
<node pkg="ros_tutorials_topic" type="topic_publisher" name="topic_publisher2"/>
<node pkg="ros_tutorials_topic" type="topic_subscriber" name="topic_subscriber2"/>
</launch> 
```

```
•pkg 패키지의 이름
•type 실제 실행 할 노드의 이름(노드명)
•name 위 type에 해당하는 노드가 실행될때 붙여지는 이름(실행명), 일반적으로는 type과 같게 설정하지만 필요에 따라 실행할때 이름을 변경하도록설정할수 있다. 
```

```
roslaunch ros_tutorials_topic union.launch --screen
```

```
rosnode list
```

```
/topic_publisher1
/topic_publisher2
/topic_subscriber1
/topic_subscriber2
/rosout
```

```
rqt_graph
```

\ <br>

![image.png](https://coda.io/contentProxy/oXCJn1awF2/blobs/bl-nrdTWrdwA0/baca5091259499249e92a4c40caa59a72f4f20620bd4752ccef5e0668cffa844e7aa9ae237334583ba7e41925e967ef3fdc2e014ed5074a0534b9c60c44ea7572005a60b9369f0a5df0a51cbd8e37350fde0c36b72727c408a543175514a07a1136ea988)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://robertchoi.gitbook.io/ros/build.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
