> For the complete documentation index, see [llms.txt](https://robertchoi.gitbook.io/ros2/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://robertchoi.gitbook.io/ros2/04-build-system.md).

# 04장 Build system

* 77Creating a launch file

<https://index.ros.org/doc/ros2/Tutorials/Launch-Files/Creating-Launch-Files/#ros2launch>

* Writing a simple publisher and subscriber (Python)

<https://index.ros.org/doc/ros2/Tutorials/Writing-A-Simple-Py-Publisher-And-Subscriber/#pypubsub>

* Writing a simple publisher and subscriber (C++)

<https://index.ros.org/doc/ros2/Tutorials/Writing-A-Simple-Cpp-Publisher-And-Subscriber/#cpppubsub>\
\
발표자 : 권준호, 김효민참석자 : 최규남, 류정필, 이태용, 김효민,김경남,박정은,안지훈, 김진성, 이창환, Yu Minsang,SANGYONG, 최종우,정하정

## + Build system 1-1

ROS2를 사용하기전에 작업환경을 구축함.실행을 하기전에 ROS2가 설치 되어있어야 함.

기본자료&#x20;

<https://www.theconstructsim.com/ros2-in-5-mins-007-how-to-create-a-ros2-overlay-workspace/>                  <https://index.ros.org/doc/ros2/Tutorials/Workspace/Creating-A-Workspace/#ros2workspace><br>

#### 디렉토리생성

```
$ mkdir -p ros2_ws/src && cd ros2_ws
```

위 코드를 입력하게 되면 다음과 같이 ros2\_ws이름의 디렉토리가가 생성 및  디렉토리 안으로 들어가는 것을 볼 수 있음

![Selection\_108.png](https://coda.io/contentProxy/w_N8GLWiAl/blobs/bl-XDqI1tk0Ki/8913cdd7f33360e5d053bc3fdc7c1af36cc02243262c35e7ac7e73e8cdb6dc02e8c9a4541f25b9f0365ed5d06d25c677fa9a6d6c062b2e8cf3d9bd258f71e6136de1b83072ee37a14ffc2f5f6490a69b9012b0654ab1accdebdbedb83fb8b621a2878886)

#### colcon에 대하여

colcon 은  ROS를 위한 범용 빌드 툴로서 개발되고 있는 툴이다. 이 툴은 ROS1, ROS2, 비 ROS 소프트웨어까지 모두 포괄하여 사용할 수 있도록 설계되었고, 기존에 설명한 catkin\_make, catkin\_make\_isolated, catkin\_tools, ament\_tools 의 모든 기능을 사용 할 수 있도록 개발되고 있다.<br>

#### colcon사용법

colcon 사용법 및 옵션들은 기존 툴들과 호환된다. 그 사용법에 대한 설명은 아래의 링크로 대신한다. 원론적으로 왜 이 범용 빌드 툴이 나오게 되었는지에 대한 고민과 의견 수렴에 대해서는 사용자 입장에서는 그렇게 크게 중요하지 않다고 생각한다. 우리에게 더 중요한 자세한 사용 방법은 이어지는 ROS2 실제 프로그래밍에서 더 깊숙히 파헤쳐 보도록 하자.\
\
&#x20;<https://cafe.naver.com/openrt/18732> <http://design.ros2.org/articles/build_tool.html> <http://colcon.readthedocs.io/> <https://github.com/colcon> <https://github.com/ros2/ros2/wiki/Colcon-Tutorial> <https://colcon.readthedocs.io/en/latest/migration/ament_tools.html> <https://colcon.readthedocs.io/en/latest/migration/catkin_make_isolated.html> <https://colcon.readthedocs.io/en/latest/migration/catkin_tools.html><br>

```
$ colcon build
```

위의 코드를 입력 하게 되면 다음과 같이 나타나는것을 볼 수 있다

![Selection\_106.png](https://coda.io/contentProxy/w_N8GLWiAl/blobs/bl-hF9lbXgE1B/dea7856e27698c7d7d51752722d1a04d04ed75c3f95a97732957fc39a9a1c89be23b95c21d8c4944fe1732881a1051ec963ec5c224537262869687cabf74ca62d650999118d8799f22f2a3d9908d0a015b7c00f8906d69d01affcff4ebfa605c3c4e6df2)

**다만, 처음 colcon build를 입력하게 된다면 오류 메시지가 뜰 수 있다.** **이 경우**

`$ sudo apt install python3-colcon-common-extensions`를 통해 해결할 수 있다.

ll (ls-l) 를 입력하여 현재 디렉토리의 자세한 내용을 알아보자

![Selection\_109.png](https://coda.io/contentProxy/w_N8GLWiAl/blobs/bl-I3Dxys_GC3/e84b8d60904960c0f38758b134b2efa79423a3ff692d229eaa5791c0fe1bcab7abbe5bd88d03c17058a52ae319c754c1fb267c9c39c73672a972beadd9c9d443506c6f86108a791797bccb8df38f8d0a6941f1e2e476a3d36aad4decf6495fa87bea243d)

마지막으로  다음 자료를 다운 받으면 기초적인  개발환경 구축이  완료된다.

```
$ source install/local_setup.bash && source install/setup.bash
```

## + Build system 1-2

\
빌드에 앞서 다음 코드를 이용해  설치 한다.

```
$ sudo apt install git-all
$ sudo apt update
```

#### 디렉토리 생성

먼저 dev\_ws(development workspace) 라는 이름의 디렉토리를 생성후 디렉토리에 접속해보자.

```
$ mkdir dev_ws
$ mkdir dev_ws/src
$ cd dev_ws/src
```

#### 샘플복제

샘플을 복제하기전 dev\_ws/src에 들어가 있어야 함. dev\_ws/src디렉토리에 들어가 있을 경우, 다음 명령어를 통해 ros\_tutorials를 복제해 보자

```
$ git clone https://github.com/ros/ros_tutorials.git -b eloquent-devel
```

이렇게 복제를 완료한 뒤에  ros\_tutorials list를 확인해 보면 다음과 같이 나타나는 것을 볼 수 있다.

![Selection\_114.png](https://coda.io/contentProxy/w_N8GLWiAl/blobs/bl-Q7DSTtoeM1/090535b562bf391181bf821241cfbff085d150cd975e0f27fa42850578dfc08cc9ff84916ce3d1b9a30ad54d8e99071e57e61b0fc082d33bf781e6f0140478f786f2b90347723c3a603223d4ff157916833e6e0c0da8d87c97e624d5aea0b2dd580624c3)

```
$ cd dev_ws/src
$ ls ros_tutorials
```

작업 공간을 샘플 패키지로 채웠으나 아직 완전히 작동하는 작업 공간은 아니다. 종속성을 해결하고 작업 공간을 먼저 구축해야 한다.

#### **패키지 종속 해결**

작업 공간을 구축하기 전 패키지 종속성을 해결해야 한다. 이미 모든 종속성을 가지고 있을 수 있지만, 최선의 방법은 복제할 때마다 종속성을 확인하는 것이다.

다음의 명령을 통해  종속을 해결할 수 있다.

```
$ sudo rosdep install -i --from-path src --rosdistro dashing -y
```

다만 그 전에 rosdep가 설치되어있지 않다면 정상적으로 작동되지 않을것이다다음과 같이 ros dep 를 설치하자

```
$ sudo apt-get install python-rosdep
$ sudo rosdep init
$ rosdep update
```

![Selection\_116.png](https://coda.io/contentProxy/w_N8GLWiAl/blobs/bl-IA3ywiamOQ/ff3dce5f7765845aaff4183834bb741bc9fd065ad51e8339261ab5448e7067f2bd3768a9fdf4bb91cfe6a05d337e045e7b4f0d6e81c8eed868f49ce2c2c5f34909d6c8b6c5321a528a2cd51bab834f137016e533d7ce2b47e33bfb66f289df5fa852f104)

#### **colcon build를 통해 작업환경 구축**

이후 colcon build를 이용하여 명령을 내리면 다음과 같은 결과를 얻을 수 있다.<br>

![Selection\_113.png](https://coda.io/contentProxy/w_N8GLWiAl/blobs/bl-URw659FW-Z/3685e301e4e19b6a623ed2a6f296d2ddbc1ded7dfa2b28574fde5428f1d998c21bdb619012f23b00ecf12661602428f9421bf9b534546bbf36fb7b3cc914f5cd8d268a47a64ad89c9aeddea9441d7e3141a71a0f4aec5da1590ac80dbdf47ec1b693e358)

#### **Overlay 수정**

turtlesim 창의 제목 표시줄을 편집하여 오버레이에서 turtlesim을 수정할 수 있다. 다음의 디렉토리 내에서 turtle\_frame.cpp텍스트를 수정해보자.

```
$ cd dev_ws/src/ros_tutorials/turtlesim/src
$ gedit turtle_frame.cpp
```

**turtle\_frame.cpp텍스트에 들어갔다면** **setWindowTitle("TurtleSim")** **의** **”TurtleSim”** **을** **”MyTurtleSim”** **로 수정하고 저장하자**

```
#include "turtlesim/turtle_frame.h"

#include <QPointF>

#include <cstdlib>
#include <ctime>

#define DEFAULT_BG_R 0x45
#define DEFAULT_BG_G 0x56
#define DEFAULT_BG_B 0xff
https://www.icbanq.com/A03_webinar/B01_webiWork/seminar_view.do?seminar_number=403https://www.icbanq.com/A03_webinar/B01_webiWork/seminar_view.do?seminar_number=403
namespace turtlesim
{

TurtleFrame::TurtleFrame(rclcpp::Node::SharedPtr& node_handle, QWidget* parent, Qt::WindowFlags f)
: QFrame(parent, f)
, path_image_(500, 500, QImage::Format_ARGB32)
, path_painter_(&path_image_)
, frame_count_(0)
, id_counter_(0)
{
  setFixedSize(500, 500);
  setWindowTitle("TurtleSim");

  srand(time(NULL));

  update_timer_ = new QTimer(this);
  update_timer_->setInterval(16);
  update_timer_->start();

  connect(update_timer_, SIGNAL(timeout()), this, SLOT(onUpdate()));

  nh_ = node_handle;
  rcl_interfaces::msg::IntegerRange range;
  range.from_value = 0;
  range.to_value = 255;
 중략..._value = 255;
```

```
 중략...
```

이후 이전에 colcon build를 실행한 터미널 창으로 돌아가 colcon build를 재실행한다. 다음을 통해 주 ROS 2 환경을 "언더레이"로 제공하므로 오버레이를 "위에" 구축할 수 있다

```
$ source /opt/ros/dashing/setup.bash
```

그후 dev\_ws디렉토리에서 오버레이를 소싱한다

```
$. install/local_setup.bash
```

그 다음 터틀심을 실행하면 창의 이름이 바뀌어 있다는것을 확인할 수 있다.하지만 언더레이가 여전히 손상되지 않았는지 확인하려면 새 터미널을 열고 다시 실행해보면 원래대로 돌아오는것을 알 수 있다.![Selection\_117.png](https://coda.io/contentProxy/w_N8GLWiAl/blobs/bl-ouryIJ-cpE/fc83ff18b7c70a96e8a04a096c27f4515da88482f163bc4025225b25904cb535ae9dc7b6a18a3dd9213e859073e680243d3a59d2659c4a30fd6733d6078ad0b6e754e7ce1b445b4daebc546a1b26b31157eb9bbfc8773895ec5da95905ba3c4e2a8f0edd)\ <br>

## + Creating a launch file

\
노드를 실행할 때 마다 terminal을 새로 열어서 실행을 한다는 것은 귀찮은 일임.여러노드를 한번에 열수 있게 Launch file을 제공함.

```
$ mkdir launch
$ touch turtlesim_mimic_launch.py
```

### turtlesim\_mimic\_launch.py

```
from  launch import LaunchDescription
from launch_ros.actions import Node

def generate_launch_description():
    return LaunchDescription([
        Node(
            package='turtlesim',
            node_namespace='turtlesim1',
            node_executable='turtlesim_node',
            node_name='sim'
        ),
        Node(
            package='turtlesim',
            node_namespace='turtlesim2',
            node_executable='turtlesim_node',
            node_name='sim'
        ),
        Node(
            package='turtlesim',
            node_executable='mimic',
            node_name='mimic',
            remappings=[
                ('/input/pose', '/turtlesim1/turtle1/pose'),
                ('/output/cmd_vel', '/turtlesim2/turtle1/cmd_vel'),
            ]
        )
    ])
```

위의 sim node가 동일해 보이지만 node\_namespace로 구분되기 때문에 괜찮음.

<https://github.com/ros/ros_tutorials/blob/melodic-devel/turtlesim/tutorials/mimic.cpp>

mimic node의 경우 remapping을 사용하는 것을 살펴보면,mimic의 /input/pose topic을 /turtlesim1/turtle1/pose로 /output/cmd\_vel topic을 /turtlesim2/turtle1/cmd\_vel로 재설정 함.

결국 /turtlesim1/turtle1/pose(위치)가 mimic의 /input/pose 입력으로 들어가고 mimic의 출력 /output/cmd\_vel(속도)이 /turtlesim2/turtle1/cmd\_vel로 연결된다.

```
$ ros2 launch turtlesim_mimic_launch.py
```

\* 실행시 turtlesim이 설치되어 있어야 동작 되는 것으로 보임.

```
$ sudo apt install ros-dashing-turtlesim
```

rqt\_graph로 현재 node의 관계를 좀더 직관적으로 살펴볼수 있다.

```
$ rqt_graph
```

실제 동작을 확인해 보자.

```
$ ros2 topic pub -r 1 /turtlesim1/turtle1/cmd_vel geometry_msgs/msg/Twist '{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: -1.8}}'
```

![](https://lh3.googleusercontent.com/vi_I0puNxfQj7KFpfWJU0vYElstCja_Uv1zquk51HypkGeEf8S0iL5kZTMVq0RGssgs1ebyBxL70vGt69rtw2DpGyl4Wrf6htY9psLKtKdCKKBz0mhihJiO_hph1ad8jDbG_gS81)

rqt\_graph에 Group을 0으로 설정하면 예와 동일하게 출력됨.

![](https://lh4.googleusercontent.com/0RrD93gornUI4K-J5YUygcE2r8p_EFMs0sYl2zHPEZP7qilIP8Ij9sU0ME4NakDjb8GQyY-39afqLyk-8ObDYG9uq4Ic9CEJjBoJH5EoVFfpMGvQ8NkbBcijpXnWyB97EVqb_voQ)

## + Creating a ROS 2 package

기본 자료 : <https://index.ros.org/doc/ros2/Tutorials/Creating-A-ROS2-Package/#createpkg><br>

#### 패키지에 대하여

패키지는  ROS 2 코드를 위한 컨테이너라고 생각할 수 있다. 만약 코드를 설치하거나 다른 사람들과 공유할 수 있기를 원한다면, 그것을 패키지로 정리해야 한다. 이것으로,  자신의 작품을 공유할 수 있고 다른 사람들이 그것을 쉽게 만들고 사용할 수 있게 할 수 있다.\
ROS 2의 패키지 생성은 ament를 빌드 시스템으로, colcon을 빌드 도구로 사용한다. 다른 빌드 유형이 존재하나 공식적으로 지원되는 CMake 또는 Python을 사용하여 패키지를 생성할 수 있다.<br>

#### **패키지 생성**

다음과 같이 dev\_ws/src 디렉토리 내에서 패키지를 생성한다

```
$ ros2 pkg create --build-type ament_cmake --node-name my_node my_package
```

이 튜토리얼의 경우 패키지에 간단한 Hello World 유형 실행 파일을 생성하는 선택적 인수 --node-name을 사용한다. 다음의 명령어를 통해 본 메시지를 받게된다.이 를통해 새 패키지에 대해 자동으로 생성된 파일을 볼 수 있다

![Selection\_118.png](https://coda.io/contentProxy/w_N8GLWiAl/blobs/bl-lKhardhsV7/15e34c87db89c6ca53c51cbd4b9d342e0a4b502cc12d1b21c2c1953e69e96331e07a6d4bab255b59f26422cee91bae8d8ad8298184ae4709278188142e5d582cb3455b9a46ee7e1370b0f8ec29ad88d5a7550cb963b25449afa8b5c585fa70b65986a5cc)

#### 패키지 구축

작업영역에 패키지를 넣는 것은 작업영역 루트에서 콜콘 빌드를 실행하여 한 번에 많은 패키지를 만들 수 있기 때문에 특히 중요하다. 그렇지 않으면 각 패키지를 개별적으로 만들어야 할 것이다.

**다음 번에 my\_package 패키지만 구축하려면 다음을 실행하십시오.**

```
$ colcon build --packages-select my_package
```

**그런 다음 dev\_ws 디렉터리 내부에서 다음 명령을 실행하여 작업 공간을 소싱한다.**

```
$ . install/setup.bash
```

이제 작업 공간이 경로에 추가되었으므로 새 패키지의 실행 파일을 사용할 수 있다.\
패키지 생성 중 --node-name 인수를 사용하여 생성한 실행 파일을 실행하려면 다음 명령을 입력한다.

```
$ ros2 run my_package my_node
```

그결과 다음과 같은 메시지를 받게 된다.\
\
dev\_ws/src/my\_package 내부에는 자동으로 생성된 2pkg의 파일과 폴더가 표시된다.

![Selection\_119.png](https://coda.io/contentProxy/w_N8GLWiAl/blobs/bl-xp9xWTdp2g/c3448c609f3d6fd2dd6bd9d96e31d6acf9ebdf742964f8b075772edf10584e15338608ebac97f5a8247869432df838deb3153148c38e612f7d4d88df5ef607dd1a070946e40756f1170604a133b2715a32f6682fa4bf1566fffac203eca69a90f04d1ab3)

```
CMakeLists.txt  include  package.xml  src
 Customize package.xml
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
 <name>my_package</name>
 <version>0.0.0</version>
 <description>TODO: Package description</description>
 <maintainer email="user@todo.todo">user</maintainer>
 <license>TODO: License declaration</license>

 <buildtool_depend>ament_cmake</buildtool_depend>

 <test_depend>ament_lint_auto</test_depend>
 <test_depend>ament_lint_common</test_depend>

 <export>
   <build_type>ament_cmake</build_type>
 </export>
</package>
```

**내용중 7번 라인이자동으로 채워지지 않은 경우 7번 라인에 이름과 이메일을 입력하십시오. 그런 다음 라인 6에서 다음 설명을 편집하여 패키지를 요약한다.**

```
<description>Beginner developer tutorials practice package</description>
```

**그다음, 다음과 같이 8번라인의 라이센스를 업데이트한다**

```
<license>Apache License 2.0</license>
```

라이센스 태그 아래에 \_depended로 끝나는 태그 이름이 있다. 여기가  package.xml이 colcon을 검색할 다른 패키지에 대한 의존성을 나열할 것이다. my\_package는 단순하고 의존성이 전혀 없지만 이 공간이 다가오는 튜토리얼에서 활용되고 있는 것을 볼 수 있을 것이다.<br>

## + Writing a simple publisher and subscriber (Python)

\
**topic으로 string message를 처리하는 node를 작성한다.**

| **rclpy**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <http://docs.ros2.org/eloquent/api/rclpy/>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| <p><strong>create\_publisher</strong>(msg\_type, topic, qos\_profile, \*, callback\_group=None, event\_callbacks=None)Create a new publisher.<strong>Parameters</strong></p><ul><li><strong>msg\_type</strong> – The type of ROS messages the publisher will publish.</li><li><strong>topic</strong> (<strong>str</strong>) – The name of the topic the publisher will publish to.</li><li><strong>qos\_profile</strong> (<strong>Union</strong>\[<a href="http://docs.ros2.org/eloquent/api/rclpy/api/qos.html#rclpy.qos.QoSProfile">QoSProfile</a>, <strong>int</strong>]) – A QoSProfile or a history depth to apply to the publisher. In the case that a history depth is provided, the QoS history is set to RMW\_QOS\_POLICY\_HISTORY\_KEEP\_LAST, the QoS history depth is set to the value of the parameter, and all other QoS settings are set to their default values.</li><li><strong>callback\_group</strong> (<strong>Optional</strong>\[<a href="http://docs.ros2.org/eloquent/api/rclpy/api/execution_and_callbacks.html#rclpy.callback_groups.CallbackGroup">CallbackGroup</a>]) – The callback group for the publisher’s event handlers. If None, then the node’s default callback group is used.</li><li><strong>event\_callbacks</strong> (<strong>Optional</strong>\[<strong>PublisherEventCallbacks</strong>]) – User-defined callbacks for middleware events.</li></ul><p><strong>Return type</strong><a href="http://docs.ros2.org/eloquent/api/rclpy/api/topics.html#rclpy.publisher.Publisher">Publisher</a><strong>Returns</strong>The new publisher.</p>                                                                                                                                                                                                                                                                                                                        |
| <p><strong>create\_subscription</strong>(msg\_type, topic, callback, qos\_profile, \*, callback\_group=None, event\_callbacks=None, raw=False)Create a new subscription.<strong>Parameters</strong></p><ul><li><strong>msg\_type</strong> – The type of ROS messages the subscription will subscribe to.</li><li><strong>topic</strong> (<strong>str</strong>) – The name of the topic the subscription will subscribe to.</li><li><strong>callback</strong> (<strong>Callable</strong>\[\[\~MsgType], None]) – A user-defined callback function that is called when a message is received by the subscription.</li><li><strong>qos\_profile</strong> (<strong>Union</strong>\[<a href="http://docs.ros2.org/eloquent/api/rclpy/api/qos.html#rclpy.qos.QoSProfile">QoSProfile</a>, <strong>int</strong>]) – A QoSProfile or a history depth to apply to the subscription. In the case that a history depth is provided, the QoS history is set to RMW\_QOS\_POLICY\_HISTORY\_KEEP\_LAST, the QoS history depth is set to the value of the parameter, and all other QoS settings are set to their default values.</li><li><strong>callback\_group</strong> (<strong>Optional</strong>\[<a href="http://docs.ros2.org/eloquent/api/rclpy/api/execution_and_callbacks.html#rclpy.callback_groups.CallbackGroup">CallbackGroup</a>]) – The callback group for the subscription. If None, then the nodes default callback group is used.</li><li><strong>event\_callbacks</strong> (<strong>Optional</strong>\[<strong>SubscriptionEventCallbacks</strong>]) – User-defined callbacks for middleware events.</li><li><strong>raw</strong> (<strong>bool</strong>) – If True, then received messages will be stored in raw binary representation.</li></ul><p><strong>Return type</strong><a href="http://docs.ros2.org/eloquent/api/rclpy/api/topics.html#rclpy.subscription.Subscription">Subscription</a></p> |
| <p>rclpy.<strong>spin</strong>(node, executor=None)Execute work and block until the context associated with the executor is shutdown.Callbacks will be executed by the provided executor.This function blocks.<strong>Parameters</strong></p><ul><li><strong>node</strong> (<a href="http://docs.ros2.org/eloquent/api/rclpy/api/node.html#rclpy.node.Node">Node</a>) – A node to add to the executor to check for work.</li><li><strong>executor</strong> (<a href="http://docs.ros2.org/eloquent/api/rclpy/api/execution_and_callbacks.html#rclpy.executors.Executor">Executor</a>) – The executor to use, or the global executor if None.</li></ul><p><strong>Return type</strong>None</p>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| **publish**(msg)Send a message to the topic for the publisher.**Parametersmsg** (\~MsgType) – The ROS message to publish.**Raises**TypeError if the type of the passed message isn’t an instance of the provided type when the publisher was constructed.**Return type**None                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |

```
$ ros2 pkg create --build-type ament_python py_pubsub

$ wget https://raw.githubusercontent.com/ros2/examples/master/rclpy/topics/minimal_publisher/examples_rclpy_minimal_publisher/publisher_member_function.py 

$ wget 
https://raw.githubusercontent.com/ros2/examples/master/rclpy/topics/minimal_subscriber/examples_rclpy_minimal_subscriber/subscriber_member_function.py 

$ ls
__init__.py  publisher_member_function.py

$ tree
.
├── package.xml
├── py_pubsub
│   ├── __init__.py
│   ├── publisher_member_function.py
│   └── subscriber_member_function.py
├── resource
│   └── py_pubsub
├── setup.cfg
├── setup.py
└── test
    ├── test_copyright.py
    ├── test_flake8.py
    └── test_pep257.py
```

| publisher\_member\_function.py                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Column 1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| <p>import rclpyfrom rclpy.node import Node<br>from std\_msgs.msg import String<br><br><strong>class</strong> <strong>MinimalPublisher</strong>(Node):<strong>=> Node를 상속받아서 새로운 class를 생성</strong><br>    <strong>def</strong> **init**(self):        super()<strong>.</strong>**init**('minimal\_publisher')        <strong>=> 부모 class에게 현재 Node name 전달</strong><br>        self<strong>.</strong>publisher\_ <strong>=</strong> self<strong>.</strong>create\_publisher(String, 'topic', 10)        <strong>=> node publisher가 Message type String을 사용하고 ‘topic’ 이라는 topic name을 사용하며 queue의 크기 10 으로 정의함.</strong><br>        timer\_period <strong>=</strong> 0.5  # seconds        self<strong>.</strong>timer <strong>=</strong> self<strong>.</strong>create\_timer(timer\_period, self<strong>.</strong>timer\_callback)        <strong>=> 0.5초 마다 callback 함수를 호출하도록 timer 설정</strong><br>        self<strong>.</strong>i <strong>=</strong> 0<br>    <strong>def</strong> <strong>timer\_callback</strong>(self):        msg <strong>=</strong> String()        msg<strong>.</strong>data <strong>=</strong> 'Hello World: %d' <strong>%</strong> self<strong>.</strong>i <strong>=> message 정의</strong><br>        self<strong>.</strong>publisher\_<strong>.</strong>publish(msg) <strong>=> message 전송</strong><br>        self<strong>.</strong>get\_logger()<strong>.</strong>info('Publishing: "%s"' <strong>%</strong> msg<strong>.</strong>data) <strong>=> console에 출력</strong><br>        self<strong>.</strong>i <strong>+=</strong> 1<br><br><strong>def</strong> <strong>main</strong>(args<strong>=None</strong>):    rclpy<strong>.</strong>init(args<strong>=</strong>args)<br>    minimal\_publisher <strong>=</strong> MinimalPublisher()<br>    rclpy<strong>.</strong>spin(minimal\_publisher)<br>    # Destroy the node explicitly    # (optional - otherwise it will be done automatically    # when the garbage collector destroys the node object)    minimal\_publisher<strong>.</strong>destroy\_node()    rclpy<strong>.</strong>shutdown()<br><br><strong>if</strong> **name** <strong>==</strong> '**main**':    main()</p> |

|                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Column 1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| <p>import rclpyfrom rclpy.node import Node<br>from std\_msgs.msg import String<br><br><strong>class</strong> <strong>MinimalSubscriber</strong>(Node):<strong>=> Node를 상속받아서 새로운 class를 생성</strong><br>    <strong>def</strong> **init**(self):        super()<strong>.</strong>**init**('minimal\_subscriber')        self<strong>.</strong>subscription <strong>=</strong> self<strong>.</strong>create\_subscription(            String,            'topic',            self<strong>.</strong>listener\_callback,            10) <strong>=> create\_publish()와의 차이점은 message 수신시 대응할 callback 함수만 연결해 주면 된다.</strong>        self<strong>.</strong>subscription  # prevent unused variable warning<br>    <strong>def</strong> <strong>listener\_callback</strong>(self, msg):        self<strong>.</strong>get\_logger()<strong>.</strong>info('I heard: "%s"' <strong>%</strong> msg<strong>.</strong>data) <strong>=> 수신한 message를 console에 출력함.</strong><br><strong>def</strong> <strong>main</strong>(args<strong>=None</strong>):    rclpy<strong>.</strong>init(args<strong>=</strong>args)<br>    minimal\_subscriber <strong>=</strong> MinimalSubscriber()<br>    rclpy<strong>.</strong>spin(minimal\_subscriber)<br>    # Destroy the node explicitly    # (optional - otherwise it will be done automatically    # when the garbage collector destroys the node object)    minimal\_subscriber<strong>.</strong>destroy\_node()    rclpy<strong>.</strong>shutdown()<br><br><strong>if</strong> **name** <strong>==</strong> '**main**':    main()</p> |

|                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Column 1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| <p>\<?xml version="1.0"?>\<?xml-model href="<http://download.ros.org/schema/package_format3.xsd>" schematypens="[http://www.w3.org/2001/XMLSchema"?>\&#x3C;package](http://www.w3.org/2001/XMLSchema"?>\&#x3C;package) format="3">  \<name>py\_pubsub\</name>  \<version>0.0.0\</version>  \<description>Examples of minimal publisher /subscriber using rclpy\</description>  \<maintainer email="<mrthinks@gmail.com>">mrthink\</maintainer>  \<license>Apache License 2.0\</license><br>  \<buildtool\_depend>ament\_python\</buildtool\_depend><br>  \<test\_depend>ament\_copyright\</test\_depend>  \<test\_depend>ament\_flake8\</test\_depend>  \<test\_depend>ament\_pep257\</test\_depend>  \<test\_depend>python3-pytest\</test\_depend><br>  \<export>    \<build\_type>ament\_python\</build\_type>    \<exec\_depend>rclpy\</exec\_depend>    \<exec\_depend>std\_msgs\</exec\_depend>  \</export>\</package></p> |

수정 사항중 dependency부부은 python code에서 import하는 python package를 추가하면 된다.

|                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Column 1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| <p>from setuptools import setup<br>package\_name = 'py\_pubsub'<br>setup(    name=package\_name,    version='0.0.0',    packages=\[package\_name],    data\_files=\[        ('share/ament\_index/resource\_index/packages',            \['resource/' + package\_name]),        ('share/' + package\_name, \['package.xml']),    ],    install\_requires=\['setuptools'],    zip\_safe=True,    maintainer='mrthink',    maintainer\_email='<mrthinks@gmail.com>',    description='Examples of minimal publisher/subscriber using rclpy',    license='Apache License 2.0',    tests\_require=\['pytest'],    entry\_points={        'console\_scripts': \[           'talker = py\_pubsub.publisher\_member\_function:main',            'listener = py\_pubsub.subscriber\_member\_function:main',        ],    },)<br></p> |

|          |
| -------- |
| Column 1 |
|          |

setup.cfg는 수정없이 사용. setuptool에게 생성한 실행결과물이 lib 디렉토리에 있다고 알려줌.\
새로운 package build를 하자.$ colcon build --packages-select py\_pubsub\
이제 두 node의 동작을 확인하자.$ . install/setup.bash$ ros2 run py\_pubsub talker\
$ . install/setup.bash$ ros2 run py\_pubsub listener<br>

## + Writing a simple publisher and subscriber (C++)

\
전체 흐름은 python과 동일함.\
$ ros2 pkg create --build-type ament\_cmake cpp\_pubsub\
\
$ wget -O publisher\_member\_function.cpp <https://raw.githubusercontent.com/ros2/examples/master/rclcpp/minimal_publisher/member_function.cpp>\
\
$ wget -O subscriber\_member\_function.cpp <https://raw.githubusercontent.com/ros2/examples/master/rclcpp/minimal_subscriber/member_function.cpp>\
$ tree.├── CMakeLists.txt├── include│   └── cpp\_pubsub├── package.xml└── src    ├── publisher\_member\_function.cpp    └── subscriber\_member\_function.cpp\
<https://github.com/ros2/rclcpp>: rclcpp provides the standard C++ API for interacting with ROS 2.<br>

|                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Column 1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| #include \<chrono>#include \<memory>#include "rclcpp/rclcpp.hpp"#include "std\_msgs/msg/string.hpp"using namespace std::chrono\_literals;/\* This example creates a subclass of Node and uses std::bind() to register a \* member function as a callback from the timer. \*/class MinimalPublisher : public rclcpp::Node{public:  MinimalPublisher()  : Node("minimal\_publisher"), count\_(0) **=> count\_를 0으로 초기화**  {    publisher\_ = this->create\_publisher\<std\_msgs::msg::String>("topic", 10);   **=> Message type으로 String을 사용하고 topic 이름을 "topic"으로 정하고 queue 크기를 10으로 설정함.**    timer\_ = this->create\_wall\_timer(      500ms, std::bind(\&MinimalPublisher::timer\_callback, this));    **=> 0.5초마다 callback 함수를 호출하도록 설정함.**  }private:  void timer\_callback()  {    auto message = std\_msgs::msg::String();    message.data = "Hello, world! " + std::to\_string(count\_++);    **=> message 생성.**    RCLCPP\_INFO(this->get\_logger(), "Publishing: '%s'", message.data.c\_str());    **=> console에 내용 출력.**    publisher\_->publish(message);    **=> Message 발송.**  }  rclcpp::TimerBase::SharedPtr timer\_;  rclcpp::Publisher\<std\_msgs::msg::String>::SharedPtr publisher\_;  size\_t count\_;};int main(int argc, char \* argv\[]){  rclcpp::init(argc, argv);  rclcpp::spin(std::make\_shared\<MinimalPublisher>());  rclcpp::shutdown();  return 0;} |

|                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Column 1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| #include \<memory> #include "rclcpp/rclcpp.hpp" #include "std\_msgs/msg/string.hpp" using std::placeholders::\_1; class MinimalSubscriber : public rclcpp::Node { public: MinimalSubscriber() : Node("minimal\_subscriber") { subscription\_ = this->create\_subscription\<std\_msgs::msg::String>( "topic", 10, std::bind(\&MinimalSubscriber::topic\_callback, this, \_1)); } private: void topic\_callback(const std\_msgs::msg::String::SharedPtr msg) const { RCLCPP\_INFO(this->get\_logger(), "I heard: '%s'", msg->data.c\_str()); } rclcpp::Subscription\<std\_msgs::msg::String>::SharedPtr subscription\_; }; int main(int argc, char \* argv\[]) { rclcpp::init(argc, argv); rclcpp::spin(std::make\_shared\<MinimalSubscriber>()); rclcpp::shutdown(); return 0; } |

|                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Column 1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| <p>\<?xml version="1.0"?>\<?xml-model href="<http://download.ros.org/schema/package_format3.xsd>" schematypens="[http://www.w3.org/2001/XMLSchema"?>\&#x3C;package](http://www.w3.org/2001/XMLSchema"?>\&#x3C;package) format="3">  \<name>my\_package2\</name>  \<version>0.0.0\</version>  \<description>Beginner developer tutorials practice package\</description>  \<maintainer email="<mrthinks@gmail.com>">mrthink\</maintainer>  \<license>Apache License 2.0\</license>  \<buildtool\_depend>ament\_cmake\</buildtool\_depend>  \<test\_depend>ament\_lint\_auto\</test\_depend>  \<test\_depend>ament\_lint\_common\</test\_depend>  \<export>    \<build\_type>ament\_cmake\</build\_type>    \<exec\_depend>rclcpp\</exec\_depend>    \<exec\_depend>std\_msgs\</exec\_depend>  \</export>\</package><br></p> |

|                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Column 1                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| <p>cmake\_minimum\_required(VERSION 3.5)project(cpp\_pubsub)# Default to C99if(NOT CMAKE\_C\_STANDARD)  set(CMAKE\_C\_STANDARD 99)endif()# Default to C++14if(NOT CMAKE\_CXX\_STANDARD)  set(CMAKE\_CXX\_STANDARD 14)endif()if(CMAKE\_COMPILER\_IS\_GNUCXX OR CMAKE\_CXX\_COMPILER\_ID MATCHES "Clang")  add\_compile\_options(-Wall -Wextra -Wpedantic)endif()# find dependenciesfind\_package(ament\_cmake REQUIRED)find\_package(rclcpp REQUIRED)find\_package(std\_msgs REQUIRED)# uncomment the following section in order to fill in# further dependencies manually.# find\_package(\<dependency> REQUIRED)add\_executable(talker src/publisher\_member\_function.cpp)ament\_target\_dependencies(talker rclcpp std\_msgs)add\_executable(listener src/subscriber\_member\_function.cpp)ament\_target\_dependencies(listener rclcpp std\_msgs)install(TARGETS  talker  listener  DESTINATION lib/${PROJECT\_NAME})if(BUILD\_TESTING)  find\_package(ament\_lint\_auto REQUIRED)  # the following line skips the linter which checks for copyrights  # uncomment the line when a copyright and license is not present in all source files  #set(ament\_cmake\_copyright\_FOUND TRUE)  # the following line skips cpplint (only works in a git repo)  # uncomment the line when this package is not in a git repo  #set(ament\_cmake\_cpplint\_FOUND TRUE)  ament\_lint\_auto\_find\_test\_dependencies()endif()ament\_package()<br></p> |

\
$ sudo rosdep install -i --from-path src --rosdistro dashing -y\
$ colcon build --packages-select cpp\_pubsub\
$ . install/setup.bash$ ros2 run cpp\_pubsub listener\
$ . install/setup.bash$ ros2 run cpp\_pubsub talker\
ls<br>

## + 미션

\
mimic을 수정하여 입력을 반전시켜 동작하게 하고, 이를 lunch file로 구성하여 turtle sim 동작으로 보자.\* 출력창은 1개만 뜨게 할 것.\
\
정하정<https://github.com/jung-ha-jung/ROS2/tree/master/turtlesim_invert_launch>turtle\_teleop\_key node를 launch 파일에서 실행했더니 키보드 입력시 문자열로 추가되네요.ㅠㅠ![image.png](https://coda.io/contentProxy/w_N8GLWiAl/blobs/bl-SPuAPifU7f/3108539d63d9e7dc9efec8bba1f307c45cf6554df4fa0236d80aa7eb3dc832fb9b776b26bd0a5c1708b64f5f67e3c40347f074ec73dd98642767bb96041365a45cf5b7e9d41737f9d055cb873cd0913bb33ea8c882cf67ed99259527b4f4f3b00910f9a9) ![image.png](https://coda.io/contentProxy/w_N8GLWiAl/blobs/bl-hCnf1CpGrt/b2f12a67d3c96a7b119fbb08b5f43b47caaa0cbca82a53ce630cf96acd477f20feafe666f641dfa4b9f10489a72cc01d3e7c25864f2f0cca42b3d92c35cab12644f9613e643a4a0934270a2a482b880c4f0c92e0c4f8be8f6e9551ea5065205f8d60edc9).<br>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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/ros2/04-build-system.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.
