MZ 아이종 2022. 2. 1. 20:25

ROS에는 다양한 package들이 있지만, 원하는 기능을 구현하기 위해 직접 생성하여 사용하기도 한다. 

모터 구동을 위한 시작으로 0-255까지의 값을 주고받는 패키지를 생성해 보자.

 

사용버전. 노트북

˙ Samsung Ultrabook i7

˙ Ubuntu 18.04.6 LTS

˙ Ros Melodic

 

단계

1. 패키지 생성

2. package.xml 수정

3. message 파일 생성

4. publisher 파일 생성 및 코드 작성

5. subscriber 파일 생성 및 코드 작성

6. CMakeLists.txt 파일 수정

7. 실행

 

1. 패키지 생성

생성하려는 package는 topic message를 이용하여 publish, subscribe 하는 package이다.

 

package는 catkin_ws 폴더의 src 폴더에 작성한다.

아래 명령어를 입력하여 해당 폴더로 이동해 준다.

$ cd catkin_ws/src

ROS 설치후 환경설정을 하면서 단축어를 설정해 두었다면 아래와 같이 입력하여도 동일한 폴더로 이동한다.

$ cs

 

package 생성시에 중요한 점은 생성할 package의 이름과 사용할 package들이다. 

package를 생성하면서 또 package를 알아야 한다는 점이 이상할 순 있지만, C코드를 작성하면서 다른 코드의 함수나 변수를 사용하기 위해 참조한다고 생각하면 이해하면 될것이다. 

 

package는 아래의 명령어 형식으로 생성할 수 있다. 

$ catkin_create_pkg name_of_making_package depending_package1 depending_package2 depending_package3 ... #형식

$ catkin_create_pkg basic message_generation std_msgs roscpp #예시

catkin_create_pkg가 package를 생성하는 명령어이다.

name_of_making_package자리에 생성하려는 package 아름을, depending_package1...에는 의존성 package를 적어주면 된다. 이때 의존성 package의 수는 필요한 만큼 적으면 되고, 이때 실수로 누락하거나 오타로 작성한 경우에도 수정, 추가할 수 있으니 걱정하지 않아도 된다.

 

작성자의 경우 아래와 같다.

$ catkin_create_pkg basic message_generation std_msgs roscpp

#basic : package 이름
#message_generation : 의존성 package1
#std_msgs : 의존성 package2
#roscpp : 의존성 package3

message_generation : message 파일 사용시에 추가해 준다. 
std_msgs : 기본 message 방식을 사용하는경우 추가해 준다.
roscpp : 언어를 C++로 사용하는 경우 추가해 준다. 

rospy : 언어를 python으로 사용하는 경우 추가해 준다.

 

package가 생성되었다.
Terminal에서의 확인방법
폴더에서의 확인방법

 

 

2. package.xml 수정

package.xml 파일은 package를 생성하면 자동으로 생성되는 파일이다. 이는 package의 기본 정보를 저장하고 있는데 몇가지 수정사항이 있다. 

 

아래는 package.xml 파일의 코드인데 대부분 작성자에 대한 정보이며, 의존성 package에 대한 내용도 저장되어 있다.

TODO라고 되어있는 부분을 수정하면 된다.

<?xml version="1.0"?>
<package format="2">
  <name>basic</name>
  <version>0.0.0</version>
  <description>The basic package</description>

  <!-- One maintainer tag required, multiple allowed, one person per tag -->
  <!-- Example:  -->
  <!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
  <maintainer email="js@todo.todo">js</maintainer>


  <!-- One license tag required, multiple allowed, one license per tag -->
  <!-- Commonly used license strings: -->
  <!--   BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
  <license>TODO</license>


  <!-- Url tags are optional, but multiple are allowed, one per tag -->
  <!-- Optional attribute type can be: website, bugtracker, or repository -->
  <!-- Example: -->
  <!-- <url type="website">http://wiki.ros.org/basic</url> -->


  <!-- Author tags are optional, multiple are allowed, one per tag -->
  <!-- Authors do not have to be maintainers, but could be -->
  <!-- Example: -->
  <!-- <author email="jane.doe@example.com">Jane Doe</author> -->


  <!-- The *depend tags are used to specify dependencies -->
  <!-- Dependencies can be catkin packages or system dependencies -->
  <!-- Examples: -->
  <!-- Use depend as a shortcut for packages that are both build and exec dependencies -->
  <!--   <depend>roscpp</depend> -->
  <!--   Note that this is equivalent to the following: -->
  <!--   <build_depend>roscpp</build_depend> -->
  <!--   <exec_depend>roscpp</exec_depend> -->
  <!-- Use build_depend for packages you need at compile time: -->
  <!--   <build_depend>message_generation</build_depend> -->
  <!-- Use build_export_depend for packages you need in order to build against this package: -->
  <!--   <build_export_depend>message_generation</build_export_depend> -->
  <!-- Use buildtool_depend for build tool packages: -->
  <!--   <buildtool_depend>catkin</buildtool_depend> -->
  <!-- Use exec_depend for packages you need at runtime: -->
  <!--   <exec_depend>message_runtime</exec_depend> -->
  <!-- Use test_depend for packages you need only for testing: -->
  <!--   <test_depend>gtest</test_depend> -->
  <!-- Use doc_depend for packages you need only for building documentation: -->
  <!--   <doc_depend>doxygen</doc_depend> -->
  <buildtool_depend>catkin</buildtool_depend>
  <build_depend>message_generation</build_depend>
  <build_depend>roscpp</build_depend>
  <build_depend>std_msgs</build_depend>
  <build_export_depend>roscpp</build_export_depend>
  <build_export_depend>std_msgs</build_export_depend>
  <exec_depend>roscpp</exec_depend>
  <exec_depend>std_msgs</exec_depend>


  <!-- The export tag contains other, unspecified, tags -->
  <export>
    <!-- Other tools can request additional information be placed here -->

  </export>
</package>

 

maintainer, url, author의 경우는 작성자에 대한 정보이므로 본인의 이메일 주소를 적어도 되고, 그대로 주석처리해 두어도 된다.

하지만 license의 경우 주석에 나와있는대로 BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 중 하나를 선택해야 하는데, 여러 참고자료들에서 BSD를 사용하여 작성자도 BSD를 적어주었다. 

 

필요없는 주석을 지우면 아래와 같다.

<?xml version="1.0"?>
<package format="2">
  <name>basic</name>
  <version>0.0.0</version>
  <description>The basic package</description>

  <maintainer email="8ajs0114@gmail.com">js</maintainer>

  <license>BSD</license>

  <url type="website">http://wiki.ros.org/basic</url>

  <author email="8ajs0114@gmail.com">Jane Doe</author>

  <buildtool_depend>catkin</buildtool_depend>
  <build_depend>message_generation</build_depend>
  <build_depend>roscpp</build_depend>
  <build_depend>std_msgs</build_depend>
  <build_export_depend>roscpp</build_export_depend>
  <build_export_depend>std_msgs</build_export_depend>
  <exec_depend>roscpp</exec_depend>
  <exec_depend>std_msgs</exec_depend>

  <export>

  </export>
</package>

author 아래의 내용을 살펴보면 

buildtool_depend : 사용하는 builder 정보를 적어두었다. 작성자는 catkin을 이용하므로 catkin이 입력되어 있다.

build_depend, build_export_depend, exec_depend : 사용하는 의존성 package들에 대한 정보들이 적혀있다. 

해당 영역에서 가각 한번씩 작성해 주면 되고, message_generation의 경우 한번만 작성해 준다.

새로운 의존성 package가 추가되거나 수정해야할 경우 해당 내용을 추가, 수정해 주면 된다.

 

 

3. message 파일 생성

message 파일의 종류로는 topic, service, action이 있고 생성한 package폴더 안에 작성한다. 

topic의 경우는 msg, service는 srv, action은 action으로 생성해 주는데, 작성자의 경우 topic을 사용하므로 msg라는 이름으로 폴더를 생성해 준다. 

msg 폴더 안에 .msg 형식의 파일을 생성해 준다.

message 파일의 내용은 위와 같으며, int32 자료형의 data 변수를 선언해 주었다.

 

$ mkdir msg #mkdir : 폴더생성, msg : 폴더 이름
$ gedit basic_msg.msg #gedit : 편집기 이름, basic_msg : message 파일 이름, .msg : message 파일 형식

msg 폴더와 .msg.파일의 생성을 확인할 수 있다.
msg 폴더의 생성을 폴더로 확인할 수 있다.

 

 

4. publish 파일 생성 및 코드 작성

아래와 같이 명령어를 작성하여 폴더를 이동한 뒤 publish 파일을 작성해 준다. 

publish 파일과 subscribe 파일은 src 폴더에 작성한다.

$ cd .. #이전 폴더로 이동
$ cd src #src 폴더로 이동
$ gedit basic_pub.cpp #basic_pub 라는 이름으로 C++ 형식의 파일 생성

 

0-255까지의 값을 반복해서 보내주는 publish 코드는 아래와 같다.

#include <ros/ros.h> 
#include "basic/basic_msg.h" //패키지이름 / 메세지파일.h 

int main(int argc, char **argv) //main 함수의 원문
{
    ros::init(argc, argv, "basic_pub"); //초기화 "사용할 node 이름"
    ros::NodeHandle nh; //ROS시스템과 통신을 위한 노드핸들 선언
 
    ros::Publisher pub = nh.advertise<basic::basic_msg>("basic_topic",1000); 
    //nh.advertise<message파일 포함 package 이름 :: message파일 이름>("사용할 topic 이름",que 개수);
    
    ros::Rate loop_rate(2); //루프 주기를 2Hz로 설정 (1초에 2번)
    
    basic::basic_msg msg; //(message파일 포함 package 이름)::(message파일 이름) (사용하려는 변수명); 
    
    int count = 0;
 
    while(ros::ok()) //ros 가 활성화되면
    {
	for(count <= 0; count < 255 ;count++)
	{   
	    msg.data = count; //count 변수 값을 msg 하위 data 메세지에 담는다.
	    ROS_INFO("send msg = %d", msg.data);
	 
	    pub.publish(msg);
	    loop_rate.sleep();
	}

	for(count >= 255; count > 0 ;count--)
	{   
	    msg.data = count; //count 변수 값을 msg 하위 data 메세지에 담는다.
	    ROS_INFO("send msg = %d", msg.data);
	 
	    pub.publish(msg);
	    loop_rate.sleep();
	}
    }
    return 0;
}

 

 

5. subscribe 파일 생성 및 코드 작성

subscribe 파일도 src폴더에서 동일하게 작성한다.

$ gedit basic_sub.cpp #basic_sub라는 이름의 C++형식의 파일 생성

 

publish된 값을 받는 subscribe 코드는 아래와 같다.

#include <ros/ros.h>
#include "basic/basic_msg.h"

void msgCallback(const basic::basic_msg &msg)  //(const message파일 포함 package 이름:: message파일 이름 &사용하려는 변수명)
{
    ROS_INFO("receive msg = %d", msg.data);
}
 
int main(int argc, char **argv)
{
    ros::init(argc, argv, "basic_sub"); //pub 쪽 node와 이름이 같지 않도록 주의 
    ros::NodeHandle nh;
    
    ros::Subscriber sub = nh.subscribe("basic_topic",100,msgCallback); //pub쪽 topic과 이름이 같도록 주의  
    ros::spin(); //어떤 값이 들어오기 전까지 대기 (다시 위로 올라감)
    return 0;
}

 

 

 

6. CMakeLists.txt 파일 수정

publish 코드와 subscribe코드를 작성하였으면 CMakeLists.txt 파일을 수정해 주어야 한다. 

CMakeLists.txt 파일에서 의존성 package를 추가, 수정할 수도 있고 사용하는 msg, srv, action 파일들도 추가할 수 있다. 

아래는 CMakeLists.txt 파일의 원본이다. 

cmake_minimum_required(VERSION 3.0.2)
project(basic)

## Compile as C++11, supported in ROS Kinetic and newer
# add_compile_options(-std=c++11)

## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
## is used, also find other catkin packages
find_package(catkin REQUIRED COMPONENTS
  message_generation
  roscpp
  std_msgs
)

## System dependencies are found with CMake's conventions
# find_package(Boost REQUIRED COMPONENTS system)


## Uncomment this if the package has a setup.py. This macro ensures
## modules and global scripts declared therein get installed
## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
# catkin_python_setup()

################################################
## Declare ROS messages, services and actions ##
################################################

## To declare and build messages, services or actions from within this
## package, follow these steps:
## * Let MSG_DEP_SET be the set of packages whose message types you use in
##   your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
## * In the file package.xml:
##   * add a build_depend tag for "message_generation"
##   * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET
##   * If MSG_DEP_SET isn't empty the following dependency has been pulled in
##     but can be declared for certainty nonetheless:
##     * add a exec_depend tag for "message_runtime"
## * In this file (CMakeLists.txt):
##   * add "message_generation" and every package in MSG_DEP_SET to
##     find_package(catkin REQUIRED COMPONENTS ...)
##   * add "message_runtime" and every package in MSG_DEP_SET to
##     catkin_package(CATKIN_DEPENDS ...)
##   * uncomment the add_*_files sections below as needed
##     and list every .msg/.srv/.action file to be processed
##   * uncomment the generate_messages entry below
##   * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)

## Generate messages in the 'msg' folder
# add_message_files(
#   FILES
#   Message1.msg
#   Message2.msg
# )

## Generate services in the 'srv' folder
# add_service_files(
#   FILES
#   Service1.srv
#   Service2.srv
# )

## Generate actions in the 'action' folder
# add_action_files(
#   FILES
#   Action1.action
#   Action2.action
# )

## Generate added messages and services with any dependencies listed here
# generate_messages(
#   DEPENDENCIES
#   std_msgs
# )

################################################
## Declare ROS dynamic reconfigure parameters ##
################################################

## To declare and build dynamic reconfigure parameters within this
## package, follow these steps:
## * In the file package.xml:
##   * add a build_depend and a exec_depend tag for "dynamic_reconfigure"
## * In this file (CMakeLists.txt):
##   * add "dynamic_reconfigure" to
##     find_package(catkin REQUIRED COMPONENTS ...)
##   * uncomment the "generate_dynamic_reconfigure_options" section below
##     and list every .cfg file to be processed

## Generate dynamic reconfigure parameters in the 'cfg' folder
# generate_dynamic_reconfigure_options(
#   cfg/DynReconf1.cfg
#   cfg/DynReconf2.cfg
# )

###################################
## catkin specific configuration ##
###################################
## The catkin_package macro generates cmake config files for your package
## Declare things to be passed to dependent projects
## INCLUDE_DIRS: uncomment this if your package contains header files
## LIBRARIES: libraries you create in this project that dependent projects also need
## CATKIN_DEPENDS: catkin_packages dependent projects also need
## DEPENDS: system dependencies of this project that dependent projects also need
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES basic
#  CATKIN_DEPENDS message_generation roscpp std_msgs
#  DEPENDS system_lib
)

###########
## Build ##
###########

## Specify additional locations of header files
## Your package locations should be listed before other locations
include_directories(
# include
  ${catkin_INCLUDE_DIRS}
)

## Declare a C++ library
# add_library(${PROJECT_NAME}
#   src/${PROJECT_NAME}/basic.cpp
# )

## Add cmake target dependencies of the library
## as an example, code may need to be generated before libraries
## either from message generation or dynamic reconfigure
# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

## Declare a C++ executable
## With catkin_make all packages are built within a single CMake context
## The recommended prefix ensures that target names across packages don't collide
# add_executable(${PROJECT_NAME}_node src/basic_node.cpp)

## Rename C++ executable without prefix
## The above recommended prefix causes long target names, the following renames the
## target back to the shorter version for ease of user use
## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node"
# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")

## Add cmake target dependencies of the executable
## same as for the library above
# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

## Specify libraries to link a library or executable target against
# target_link_libraries(${PROJECT_NAME}_node
#   ${catkin_LIBRARIES}
# )

#############
## Install ##
#############

# all install targets should use catkin DESTINATION variables
# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html

## Mark executable scripts (Python etc.) for installation
## in contrast to setup.py, you can choose the destination
# catkin_install_python(PROGRAMS
#   scripts/my_python_script
#   DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
# )

## Mark executables for installation
## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html
# install(TARGETS ${PROJECT_NAME}_node
#   RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
# )

## Mark libraries for installation
## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html
# install(TARGETS ${PROJECT_NAME}
#   ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
#   LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
#   RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}
# )

## Mark cpp header files for installation
# install(DIRECTORY include/${PROJECT_NAME}/
#   DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
#   FILES_MATCHING PATTERN "*.h"
#   PATTERN ".svn" EXCLUDE
# )

## Mark other files for installation (e.g. launch and bag files, etc.)
# install(FILES
#   # myfile1
#   # myfile2
#   DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
# )

#############
## Testing ##
#############

## Add gtest based cpp test target and link libraries
# catkin_add_gtest(${PROJECT_NAME}-test test/test_basic.cpp)
# if(TARGET ${PROJECT_NAME}-test)
#   target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
# endif()

## Add folders to be run by python nosetests
# catkin_add_nosetests(test)

 

필요한 부분만 주석을 해제하고 나머지는 지우면 아래 코드와 같다.

cmake_minimum_required(VERSION 3.0.2)
project(basic)

find_package(catkin REQUIRED COMPONENTS
  message_generation
  roscpp
  std_msgs
)

 add_message_files(
   FILES
   Message1.msg
   Message2.msg
 )

 generate_messages(
   DEPENDENCIES
   std_msgs
 )

catkin_package(
  LIBRARIES basic
  CATKIN_DEPENDS message_generation roscpp std_msgs
)


include_directories(
  include
  ${catkin_INCLUDE_DIRS}
)

add_executable(${PROJECT_NAME}_node src/basic_node.cpp)


add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

target_link_libraries(${PROJECT_NAME}_node
   ${catkin_LIBRARIES}
 )

 

주석의 경우 어떤 부분이 어떻게 쓰이는지 작성되어 있지만 코드적으로는 필요가 없고 지금 사용하려는 기능과는 무관하니 지워두도록 하겠다. 이후에 공부를 하면서 추가하도록 하자.

 

먼저 find_package 부분을 보면 의존성 package들이 적혀있는데, 이 부분에 추가해 주거나 수정해 주면 해당 package를 사용할 수도 지울 수도 있다.

아래는 rospy를 추가한 예시이다.

#원본
find_package(catkin REQUIRED COMPONENTS
  message_generation
  roscpp
  std_msgs
)

#rospy를 추가한 경우
find_package(catkin REQUIRED COMPONENTS
  message_generation
  roscpp
  rospy
  std_msgs
)

 

add_message_files의 경우 본인이 추가적으로 작성한 message 파일들을 추가해 주면 된다.

ros에서 제공되는 message는 추가해 주지 않아도 된다.

action과 service의 경우도 동일하게 추가해 주면 된다.

#원본
add_message_files(
   FILES
   Message1.msg
   Message2.msg
 )
 
 #수정본
add_message_files(
   FILES
   basic_msg.msg
)

 

genetate_messages의 경우 추가된 message나 service의 의존성 package들을 작성하라고 하는데, 이 경우 따로 수정할 부분은 없다. 

 

catkin_package의 경우 따로 수정할 내용은 없지만 CATKIN_DEPENDS의 경우 의존성 package이지만, message_generation은 제외해 주어야 한다.

#원본
catkin_package(
  LIBRARIES basic
  CATKIN_DEPENDS message_generation roscpp std_msgs
)

#수정본
catkin_package(
  LIBRARIES basic
  CATKIN_DEPENDS roscpp std_msgs
)

 

include_diretories의 경우 사용하지 않으니 넘어간다.

 

add_executabl, add_dependencies, target_link_libraries의 경우 publisher와 subscriber에 대한 내용이다.

${PROJECT_NAME} 부분에 생성한 package 이름을, ${PROJECT_NAME}_node 에는 생성한 publish와 subscribe 파일의 이름을 작성해 준다.

동시에 작성하는 것이 아닌 publisher, subscriber 개별적으로 작성해 준다.

#원본
add_executable(${PROJECT_NAME}_node src/basic_node.cpp)

add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

target_link_libraries(${PROJECT_NAME}_node
   ${catkin_LIBRARIES}
)

#수정본
add_executable(basic_pub src/basic_pub.cpp)
add_executable(basic_sub src/basic_sub.cpp)

add_dependencies(basic_pub ${basic_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
add_dependencies(basic_sub ${basic_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

target_link_libraries(basic_pub
   ${catkin_LIBRARIES}
 )
target_link_libraries(basic_sub
   ${catkin_LIBRARIES}
 )

 

아래는 수정한 전체 코드이다.

cmake_minimum_required(VERSION 3.0.2)
project(basic)

find_package(catkin REQUIRED COMPONENTS
  message_generation
  roscpp
  std_msgs
)

add_message_files(
   FILES
   basic_msg.msg
)

 generate_messages(
   DEPENDENCIES
   std_msgs
 )

catkin_package(
  LIBRARIES basic
  CATKIN_DEPENDS roscpp std_msgs
)


include_directories(
  include
  ${catkin_INCLUDE_DIRS}
)

add_executable(basic_pub src/basic_pub.cpp)
add_executable(basic_sub src/basic_sub.cpp)

add_dependencies(basic_pub ${basic_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
add_dependencies(basic_sub ${basic_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

target_link_libraries(basic_pub
   ${catkin_LIBRARIES}
 )
target_link_libraries(basic_sub
   ${catkin_LIBRARIES}
 )

 

 

7. 실행

코드를 전부 수정했으면, 아래의 명령어를 입력하여 make 해 준다.

$ cd ~/catkin_ws && catkin_make #원래 입력해야할 명령어
$ cm #cs나 cw같이 ROS 환경설정 시에 단축어로 설정해 두었으면 입력하면 정상작동 한다.
     #소스를 컴파일 하는 과정이라고 생각하면 된다. 오류가 있다면 오류의 위치와 내용을 알려준다.
     #자주 사용하므로 cs, cw, cm 3가지는 설정해 두는것이 좋다.

 

완료가 되면 아래와 같이 표시된다.

 

이후 터미널 창을 3개 띄워주고 각각의 창에 아래 명령어를 차례로 입력해 준다.

#1st Terminal
$ roscore

#2nd Terminal
$ rosrun basic basic_pub

#3rd Terminal
$ rosrun basic basic_sub

#rosrun의 경우 package의 이름 node의 이름을 차례로 입력해 준다.
#생성한 publish 파일과 subscribe 파일이 각각 publisher, subscriber node가 된다.

 

roscore / rosrun basic basic_pub / rosrun basic basic_sub

roscore를 실행해 주고 publisher, subscriber를 실행시키면 publisher의 내용이 subscriber로 전송됨을 확인할 수 있다.