본문 바로가기

Study_ROS/[ROBOTIS ROS Courses]

[ROBOTIS ROS Courses] Ch7. ROS 기본 프로그래밍

728x90

Ch7. ROS 기본 프로그래밍

 

- ROS Programming 전 알아둬야 할 사항

  • 표준 단위 : 주고 받는 Message들의 단위 통일 (SI Unit 사용)
  • 좌표 표현 방식 : 정회전은 반시계 방향 (오른손 법칙). https://www.ros.org/reps/rep-0103.html#coordinate-frame-conventions 에서 각 version에 맞는 rep 찾아서 규칙 찾아보기
    • Rep (ROS Enhancement Proposal) : ROS community를 위한 design 문서 정보를 제공하거나 ROS의 새로운 feature, process, environment를 설명 
  • 프로그래밍 규칙 : wiki.org에 명시되어 있음 (http://wiki.ros.org/CppStyleGuide)
  • Package, Topic, Service, File, Library, Variable, Namespace는 under score('_') 사용
    • Ex) std_msgs, robot_node
  • Source file은 .cpp 확장자 사용
  • Header file은 .h 확장자 사용
    • 모든 header들은 다수의 inclusion에 대해 #ifndef guard로 보호받아야 하며, 아래와 같은 guard는 License Statement 바로 뒤, 그리고 모든 code들 전에 실행되어야 하고 file의 끝부분에서 끝나야 함
# ifndef PACKAGE_PATH_FILE_H
# define PACKAGE_PATH_FILE_H
...
# endif

 

  • Class, Type, Function, Method는 CamelCased (띄어쓰기 없이 대문자로 구분) 사용. 단 각자의 argument는 '_' 사용
    • Ex) class ExampleClass, void CalculateVelocity
  • Constant는 전부 대문자 사용
  • Global Variable은 거의 사용하지 않으며, 사용시 variable name 앞에 'g_'를 붙임
  • Editor 사용시 indent는 spacebar 두번. Tab키 사용 X
  • Line의 최대 길이는 120글자
  • Code는 반드시 documented 되어야 함. Doxygen을 통해 코드를 자동으로 document 함
    • Doxygen : Documentation 생성기로, Software 참조 설명문을 작성하는데 사용하는 도구. 설명문을 code 내에 작성하여 상대적으로 최신화 상태를 유지하기 용이함
  • ROS에서는 printf, cout 대신 rosconsole을 통해 출력을 수행. rosconsole의 출력은 /rosout에 publish 되어 network상의 모든 이용자가 볼 수 있음
    • rosout : 항상 기동하는 기본적인 node로, 각 node들의 debugging 정보를 가지고 있다
    • Subscribed topic
    • /rosout (rosgraph_msgs/Log) : Logging message를 publish하는 standard ROS topic
    • Published topic
    • /rosout_agg (rosgraph_msgs/Log) : /rosout에 publish된 messgae의 집계된 feed
  • Macro는 가능한 사용 X. Inline Function이나 const variable과 달리 typed, scoped 되지 않음

 

 

- Message 통신의 종류 (복습)

Description of ROS`s Message Communication

  • Topic : 연속성을 가지는 단방향 통신
  • Service : 1회성을 가지는 양방향 통신
  • Action : 기존의 서비스의 기능에서 피드백 기능 추가 

 

- roscore 실행 시의 3가지 기능

  1. ROS Master 기능을 함 (Node 정보 관리)
  2. rosout : 각종 log 기록 전담
  3. Parameter server 구동.
    • Parameter Server는 사용자가 정해놓은 각종 parameter들을 기록함. 임의의 node나 직접 명령을 통해 parameter 값을 바꿀 수 있다

 

- Topic, Service 직접 구현

1) Make Package

$ cd~/catkin_ws/src
  • catkin_ws/src : 다양한 package들이 들어가는 곳
  • ~ : Home Directory를 의미

 

$ catkin_create_pkg ros_tutorials_topic message_generation std_msgs roscpp
  • 'catkin_create_pkg' 명령어를 이용하여 'ros_tutorials_topic' 라는 이름의 package를 생성함
  • 'message_generation', 'std_msgs', 'roscpp' 는 package가 이 3개의 package에 의존성이 있음을 의미

create package

 

  • src는 source code가 들어가는 곳
  • 처음에 src 폴더는 비어있음

 

 

  • 위 두 폴더와 파일들은 package를 작성할 때 가장 기본적으로 구성되어야 함
  • include : Header File Folder
  • src : Source Code Folder
  • CMakeLists.txt : Build Setting File. ROS의 build system인 catkin은 기본적으로 CMake를 이용하므로 이 file에 build 환경을 기술한다
  • package.xml : Package Setting File. Package 이름, author, license, dependency등을 기술한다

 

$ cd ros_tutorials_topic 
$ ls
  • ls(list) 명령어를 통해 해당 directory에 있는 구성요소들을 볼 수 있음

 

 

2) Package 설정 File (package.xml) 수정

$ gedit package.xml
  • 파일을 연 후 아래의 내용들을 위 파일에 붙여넣음
  • ROS의 필수 설정 file 중 하나인 package.xml은 package 정보를 담은 xml 파일로써 package name, author, license, dependency packages 등을 기술함 
<?xml version="1.0"?>			
// xml의 버전을 의미. 1.0이상 사용 가능함을 의미. 필수적이진 않으나 Encoding을 위해 넣는 것이 좋음
<package format="2">			
// package 태그 시작점. </package>까지가 ROS package 설정 부분
<name>ros_tutorials_topic</name>	
// package의 이름. Package 생성시 입력한 이름이 사용됨
<version>0.1.0</version>		
// 버전 태그. 개인적으로 쓸 땐 큰 의미 없으나 공식 package를 만들 땐 
// 매우 중요. 뭔가 수정해서 다시 올리려면 버전을 update해서 올려야 함
<description>ROS turtorial package to learn the topic</description>
// package에 대한 대략적인 설명. 공식 package를 만들 때 해당 package에 대한 wiki 페이지가 
// 자동적으로 만들어지게 할 수 있음. wiki페이지에서 가장 위에 있는 설명란에 해당
<license>Apache 2.0</license>	
// Package 개발 시 적용된 license
<author email="pyo@robotis.com">Yoonseok Pyo</author>	
// 저자. 여려명일 시 여러 줄 작성
<maintainer email="pyo@robotis.com">Yoonseok Pyo</maintainer>
// maintanier와 author는 보통 초반에는 동일 인물이나 후에 변경 가능
// maintanier는 해당 package를 관리하는 사람
<url type="website">http://www.robotis.com</url>
// Package를 설명하는 website
<url type="repository">https://github.com/ROBOTIS-GIT/ros_tutorials.git</url>
// 이 package의 source code는 해당 github에 들어가면 찾아볼 수 있다
<url type="bugtracker">https://github.com/ROBOTIS-GIT/ros_tutorials/issues</url>
// package에서 issue가 있을 시 해당 url에 올려달라는 의미
<buildtool_depend>catkin</buildtool_depend>
// build할 때 어떤걸 쓸 것인가
<depend>roscpp</depend>		// cpp 관련 API를 불러오기 위함
<depend>std_msgs</depend>	// 어떤 message를 쓸지 표시
<depend>message_generation</depend>	// message를 만들기 위해 해당 package 사용
// Package의 의존성들
<export></export >
// ROS에서 명시하지 않은 tag명을 사용할 때 쓰임. 일반적인 경우 사용하지 않음
</package>						// package 태그 종료점

 

<build_depend>roscpp</build_depend>
<build_depend>std_msgs</build_depend>
<build_depend>message_generation</build_depend>
<run_depend>roscpp</run_depend>
<run_depend>std_msgs</run_depend>
<run_depend>message_generation</run_depend>
// 위의 긴 명령어들은 Package Format V2. 지금 명령어들은 V1
// build_depend는 build할 때 의존성, run_depend는 실행할 때의 의존성. 일반적으로는 둘이 동일

 

- xml file의 각 tag과 attribute

  • <launch>, </launch> : Launch file의 시작과 끝
  • <node> : Node 실행
    • 필수 arrtibute
    • pkg : Package 이름
    • type : 실행할 node나 실행 file의 이름
    • name : Node의 실행 이름. 일반적으로는 type과 동일. Node 내부에서 설정한 이름보다 우선적으로 사용
    • Option attribute
    • args : Node에 parameter를 전달
    • output : stdout/stderr 표시 방법 설정. 기본은 log로, $ROS_HOME/log에 작성. screen으로 설정 시 terminal에 출력
    • respawn : true일 경우 Node 종료시 자동으로 재시작
    • machine : 지정한 기기에서 node 실행
  • <machine> : Node를 실행시킬 기기를 지정정. 모든 node가 local network에서 구동되는 경우는 사용하지 않음
    • 필수 arrtibute
    • name : 기기의 이름 지정 <node> tag에서 사용하는 'machine' attribute와 대응됨
    • address : 기기의 network 주소 지정
    • env-loader : 원격 기기의 환경 파일 지정정
    • Option attribute
    • default = "true or false or never" : 해당 기기가 모든 node들의 기본 실행 기기가 될 것인지 설정
    • timeout : roslaunch에서 몇 초간 해당 기기에 대한 응답이 없으면 연결 실패로 간주할 것인지 시간을 지정
  • <include> : Launch file 내에서 다른 launch xml file을 가져옴
    • 필수 arrtibute
    • file = "$(find package_name)/path/file_name.xml" : Include할 file 이름 입력
    • Option attribute
    • ns : File을 가져올 namespace 입력
  • <remap> : Node 이름, topic 이름 등의 node에서 사용 중인 ROS 변수의 이름을 변경
    • from : remap할 원래 이름
    • to : 바꿀 이름
  • <env> : 이미 실행된 Node의 환경 변수 설정 (Launch file의 환경 변수는 수정 불가능하며 거의 쓰이지 않음 )
    • name : 설정할 환경 변수의 이름
    • value : 해당 환경 변수의 값 설정
  • <param> : Parameter 값 설정 (Parameter Server로 저장되어 여러 곳에서 참조 가능)함. 단일 parameter를 처리
    • 필수 arrtibute
    • name : Parameter 이름 설정
    • Option attribute
    • value : Parameter 값 설정
    • type : Parameter 자료형 지정(std/int/double/bool). 미지정시 roslaunch의 규칙에 따라 지정
  • <rosparam> : ROS parameter 설정 (YAML file을 이용해 parameter server의 parameter 값을 확인하고 수정). Parameter가 많은 경우 이 방식이 편함
    • 필수 arrtibute
    • file = "$(find pkg_name)/path/file_name.xml : rosparam file의 이름 입력. rosparam command로 load나 dump로 설정한 경우에만 사용
    • param = "param_name" : Parameter 이름 지정
    • Option attribute
    • command = "load or dump or delete" : rosparam에서 사용할 command 지정. 기본값은 load (load는 추가 command로 간주하며 paramater의 directory 또는 namespace를 선언하면 namespace에 선언된 다른 parameter에 추가됨)
    • ns = "namespace" : Parameter를 지정된 namespace에 scope 시킴
    • subst_value = true or false : YAML file 내에 있는 'substitution args'의 사용 여부 설정
  • <group> : 다수의 node를 group으로 묶음. ns = "namespace"를 통해 namespace 지정 가능
    • ns="namespace" : Node group을 지정된 namespace에 scope 
    • clear_params = "true or false"  : Launch 실행 전 group의 namespace parameter를 전부 제거. true인 경우 반드시 ns attribute와 같이 사용해야 함
  • <test> : 노드를 테스트할 때 사용.<node>와 비슷하지만 테스트에 사용할 수 있는 옵션들이 추가되어 있으며 respwan, output, machine attribute는 사용 불가
  • <arg> : Launch file 내부에서 지역변수처럼 사용될 값을 정의. 자주 사용
    • 필수 arrtibute
    • name : 이름 지정
    • Option attribute
    • default : 기본값 설정. 아래의 'value' attribute와 동시 사용 불가능
    • value : 값 지정 'default' attribute와 동시 사용 불가능

 

 

3) Build Setting File(CMakeLists.txt) 수정

 

  • CMakeLists.txt (Build Setting File)에 아래 코드 복사
  • CMakeLists는 source code 작성 후 execution file을 만들 때와 실제로 우리가 작성한 node를 build할 때 사용되는 option들에 대한 정보를 가진다
cmake_minimum_required(VERSION 2.8.3)
## OS에 설치된 cmake의 최소 요구 버전으로, 최신 버전 필요. 위 버전보다 높아도 상관없음

project(ros_tutorials_topic)
## 괄호 안의 이름은 package.xml에서 입력한 package의 이름과 같아야 함 
## 다르면 build가 되지 않음

find_package(catkin REQUIRED COMPONENTS 
    message_generation 
    std_msgs 
    roscpp
)
## catkin build시 요구되는 구성요소 package.
## 의존성 패키지로 message_generation, std_msgs, roscpp이 있으며 이 패키지들이 존재하지 않으면 빌드 도중에 에러 발생.
## 사용자가 만든 package가 dependency package를 먼저 설치하게 만드는 option

catkin_python_setup()
## Python 사용시 설정하는 option으로, python 설치 process인 setup.py를 부르는 역할을 한다

add_message_files(
    FILES 
    MsgTutorial.msg
)
## 메시지 선언: MsgTutorial.msg (아래에서 새로 만들 message)
## 사용하는 message file을 추가하는 option
## FILES 사용시 package folder의 msg folder 안의 .msg file들을 참조함

add_service_files(
    FILES
    Service.srv
)
## 사용하는 service file을 추가하는 option
## FILES 사용시 package folder의 srv folder 안의 .srv file들을 참조함

generate_messages(
    DEPENDENCIES 
    std_msgs
)
## 의존 message 설정 option. std_msgs가 설치되어 있지 않다면 빌드 도중에 에러가 난다.
## std_msgs build시 MsgTutorial.msg에 포함됨을 의미 : dependency가 존재함을 의미
## DEPENDENCIES option에 의해 std_msgs라는 message package를 사용하겠다는 설정

catkin_package(
    INCLUDE_DIRS include
    LIBRARIES ros_tutorials_topic 	## generaly use package`s name
    CATKIN_DEPENDS std_msgs roscpp	
    DEPENDS system_lib
)
## catkin build option으로 library, catkin build dependency, system 의존 package를 기술한다.
## INCLUDE_DIRS는 뒤에 설정한 package 내의 folder인 include의 header file을 사용하겠다는 설정
## LIBARIES는 뒤에 설정한 package의 library를 사용하겠다는 설정
## CATKIN_DEPENDS 뒤에는 roscpp나 std_msg 등 의존 package 지정
## DEPENDS는 system 의존 package를 기술

include_directories(
    ${catkin_INCLUDE_DIRS}
)
## Include directory 지정 option
## {catkin_INCLUDE_DIRS}는 각 package 내의 include folder를 의미하고 이 안의 header file을 사용하겠다는 설정
## (${catkin_INCLUDE_DIRS}, include) 작성시 package의 include folder를 사용할 것을 의미

add_library(my_first_ros_pkg
    src/${PROJECT_NAME}/my_first_ros.cpp
)
## Build후 생성할 library 지정. src/${PROJECT_NAME}/my_first_ros.cpp을 참조하여
## my_first_ros_pkg라는 library를 생성한다


## !!아래 명령어들은 주로 사용되는 명령어로, 매우 중요함!!


## topic_publisher node에 대한 build option
## -> 이 tutorial에선 topic을 보내는 publisher node와 topic을 받는 subscriber node를 만듦
## 따라서 2개의 execution file을 생성

add_executable(topic_publisher src/topic_publisher.cpp)
## Build 후 생성할 execution file을 지정
## src/topic_publisher.cpp file을 참조하여 topic_publisher라는 execution file을 생성
## execute file, target link library, 추가 dependency 등을 설정할 수 있다

add_dependencies(topic_publisher ${${PROJECT_NAME}_EXPORTED_TARGETS}
${catkin_EXPORTED_TARGETS})
## Package build에 앞서 생성해야 할 message header file이 있으면 build 전에 우선적으로 message를
## 생성하게 하는 option
## 위의 경우 topic_publisher_messgaes_cpp를 우선 build하고 topic_publisher를 build함
## topic_publisher은 node의 이름. 해당 node 생성시 src/topic_publisher.cpp 참고

target_link_libraries(topic_publisher 
    ${catkin_LIBRARIES}
)
## topic_publisher node 생성 전 link해야 하는 library와 execution file을 link해주는 option
## dependencies를 가지는 build options를 conduct 할 수 있음

## topic_subscriber node에 대한 build option
## 위와 거의 동일
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) Message File 작성

 

$ roscd ros_tutorials_topic	# roscd 사용시 directory 대신 package의 이름을 사용
  • ros_tutorials_topic package folder로 이동

 

$ add_message_files(FILES MsgTutorial.msg)
  • 위의 CMakeLists.txt에서 설정한 내용 (node에서 사용할 message인 MSGTutorial.msg를 build시에 포함)

 

$ mkdir msg  
$ cd msg  
$ gedit MsgTutorial.msg  
$ cd ..
  • ros_tutorials_topic package에 msg라는 message folder를 생성 후 해당 folder로 이동
  • gedit을 통해 MsgTutorial.msg file 작성

 

time stamp	# stamp는 'time' type의 message 
int32 data	# data는 int32 type의 message
  • MsgTutorial.msg에 위의 두 message 입력
  • time, int32 는 message의 type
    • time type은 message를 보내며 시간을 나타냄 
    • int32 type은 자료형

Message`s types

  • 일반적으로 message file인 msg와 service file인 srv는 실행 node에 포함시키기 보다는 message file만으로 구성된 독립된 package로 만드는 것이 좋다
    • Subscriber / Publisher node가 다른 computer에서 실행된다고 가정했을 때, 두 node간의 상호 의존성을 갖추기 위해 불필요한 node를 설치해야 함
    • 하지만 message만의 package를 따로 만들어주면 그 독립적인 message package만 dependency option에 추가하면 되므로 불필요한 package간의 dependency를 없앨 수 있음
    • 다만 위 예제에서는 코드를 간결하게 만들기 위해 message file을 실행 node에 포함함

 

 

5) Publisher Node 작성

 

add_executable(topic_publisher src/topic_publisher.cpp)
  • 위의 CMakeLists.txt에서 설정한 내용 (src 폴더의 topic_publisher.cpp라는 파일을 build하여 topic_publisher라는 실행 file을 만듦)

 

$ roscd ros_tutorials_topic/src  
$ gedit topic_publisher.cpp
  • ros_tutorials_topic 패키지의 소스 폴더인 src 폴더로 이동 후 소스 파일 신규 작성 및 내용 수정
  • cpp 파일에 아래 코드 복사
#include "ros/ros.h" 			    // ROS 기본 헤더파일
#include "ros_tutorials_topic/MsgTutorial.h"// MsgTutorial 메시지 파일 헤더(빌드 후 자동 생성됨)
// write to use 'MsgTutorial' message

int main(int argc, char **argv) // 노드 메인 함수
{
ros::init(argc, argv, "topic_publisher"); // 노드명 초기화 (처음에 반드시 진행되어야 함)
ros::NodeHandle nh; // ROS 시스템과 통신을 위한 노드 핸들 선언

// Publisher 선언. ros_tutorials_topic 패키지의 MsgTutorial 메시지 파일을 이용한 
// publisher ros_tutorial_pub를 작성한다.
// Topic명은 "ros_tutorial_msg" 이며, 퍼블리셔 큐(queue) 사이즈를 100개로 설정한다.
// Publish되는 messgae의 형태를 설정한다. option에서 가장 중요한 과정이다 
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 메시지에 담는다(time type)
// stamp는 msg의 member 변수

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 메시지를 표시한다(nano second)
ROS_INFO("send msg = %d", msg.data); // data 메시지를 표시한다
// ROS_INFO는 printf와 동일한 기능을 한다 (ROS에서는 printf를 사용하지 않는다)
// 무엇을 출력할지에 따라 대신 사용할 수 있는 다수의 명령어가 있다

ros_tutorial_pub.publish(msg); // 메시지(msg)를 발행한다
loop_rate.sleep(); // 위에서 정한 루프 주기에 따라 슬립에 들어간다(10Hz)
++count; // count 변수 1씩 증가
}
return 0;
}

 

 

6) Subscriber Node

 

add_executable(topic_subscriber src/topic_subscriber.cpp)
  • 위의 CMakeLists.txt에서 설정한 내용 (src 폴더의 topic_subscriber.cpp라는 파일을 build하여 topic_subscriber라는 실행 file을 만듦)

 

$ roscd ros_tutorials_topic/src  
$ gedit topic_subscriber.cpp
  • 패키지의 소스 폴더인 src 폴더로 이동 후 소스 파일 신규 작성 및 내용 수정
  • cpp 파일에 아래 코드 복사 (Publisher node의 code와 거의 유사)
#include "ros/ros.h" 
#include "ros_tutorials_topic/MsgTutorial.h" 

// 메시지 콜백 함수로써, 밑에서 설정한 ros_tutorial_msg라는 명의 토픽 메시지를 수신하였을 때 동작하는 함수
// 입력 메시지로는 ros_tutorials_topic 패키지의 MsgTutorial 메시지를 받도록 되어있다
void msgCallback(const ros_tutorials_topic::MsgTutorial::ConstPtr& msg)
{
ROS_INFO("recieve msg = %d", msg->stamp.sec); // stamp.sec 메시지를 표시한다
ROS_INFO("recieve msg = %d", msg->stamp.nsec); // stamp.nsec 메시지를 표시한다
ROS_INFO("recieve msg = %d", msg->data); // data 메시지를 표시한다
// write what will do with data received here
}

int main(int argc, char **argv) // 노드 메인 함수
{
ros::init(argc, argv, "topic_subscriber"); // 노드명 초기화
ros::NodeHandle nh; // ROS 시스템과 통신을 위한 노드 핸들 선언

// Subscriber 선언, ros_tutorials_topic 패키지의 MsgTutorial 메시지 파일을 이용한
// Subscriber ros_tutorial_sub 를 작성한다. 토픽명은 "ros_tutorial_msg" 이며,
// Subscriber 큐(queue) 사이즈를 100개로 설정한다
// Topic의 이름과 queue size는 publisher node와 반드시 같아야 한다
ros::Subscriber ros_tutorial_sub = nh.subscribe("ros_tutorial_msg", 100, msgCallback);

// 콜백함수 호출을 위한 함수로써, 메시지가 수신되기를 대기. Message 수신 전까지는 아무것도 하지 않는다
// 수신되었을 경우 콜백함수(msgCallback)를 실행한다
ros::spin();

return 0;
}

 

  • 하나의 node는 subscriber, publisher, service등의 여러 역할을 수행할 수 있다

 

ros::Publisher publisher_name = node_handle_name.advertise<package_name::message_file>("topic_name", queue_size);
ros::Subscriber subscriber_name = node_handle_name.subscribe("topic_name", queue_size, CallbackFunction_name);
  • Publisher / Subscriber node 선언 statement
  • 둘의 topic name과 queue size는 반드시 같아야 한다

 

 

7) Build ROS Node

 

- File System 관련 내용

  • Package의 source code file은 package 파일의 src, message file은 msg에 있다
    • ~/catkin_ws/src/ros_tutorials_topic/src, ~/catkin_ws/src/ros_tutorials_topic/msg
  • 이를 기반으로 build된 결과물은 catkin_ws의 build, devel 폴더에 각각 저장됨
    • build 폴더에는 catkin build시 사용된 setting 내용이 저장
    • /devel/lib/ros_tutorials_topic 폴더에는 execute file이 저장
    • /devel/include/ros_tutorials_topic 폴더에는 message 파일로부터 자동 생성된 message header file이 저장

 

$ cd ~/catkin_ws 
$ catkin_make
  • catkin 폴더로 이동 후 catkin 빌드 실행 (Publisher / Subscriber node build)
  • 의존성 확인 후 target을 build

  • 우리가 만든 message에서 사용할 C++, Javascript, Python...을 build (파란 글자)

Publisher node 선언 방식

  • Execute file이 topic publisher와 subscriber로 구성되어있음을 의미
  • source code, build, execute file 은 서로 분리되어 관리된다
  • Execute file은 아래의 directory에 있음 

Header file 자동 생성

 

8) Publisher Node 실행

 

$ roscore
$ rosrun ros_tutorials_topic topic_publisher
  • Master node 실행 후 Publisher node 실행
  • rosrun 명령어는 단일 node를 실행시킴
  • ros launch는 launch file을 통해 여러 node들을 한번에 실행시킴

publisher node 실행 결과

  • second
  • nano second
  • data(0, 1, ...) 순으로 출력
  • 위 결과는 실제로는 publish를 하는 것이 아닌, 단순히 출력만을 하는 것 (== ROS_INFO)

 

$ rqt_graph

publisher node 하나만 실행되고 있음

 

$ rostopic list
  • 현재 ROS 네트워크에서 사용중인 topic 목록 확인

$ rostopic echo /ros_tutorial_msg
  • ros_tutorial_msg의 내용 확인

 

$ rostopic info /ros_tutorial_msg
  • ros_tutorial_msg topic의 정보 확인
  • 172.16.2.73은 local host의 ip, 41439는 port 번호

 

 

$ rostopic hz /ros_tutorial_msg
  • ros_tutorial_msg topic의 주기(Hertz) 확인

 

$ rostopic bw /ros_tutorial_msg
  • ros_tutorial_msg topic의 데이터 대역폭(Bandwidth) 확인

 

 

9) Subscriber Node 실행

 

$ rosrun ros_tutorials_topic topic_subscriber
  • Subscriber node 실행

위가 publisher, 아래가 subscriber

  • Publisher node에서 publish한 message를 Subscriber node에서 subscribe하여 출력

 

$ rqt_graph
  • 실행된 node들의 통신 상태 확인

 

 

- 요약

  • topic_publisher라는 이름의 node가 ros_tutorials_topic 패키지의 MsgTutorial 메세지 파일을 ros_tutorial_pub라는 publisher를 통해 ros_topic_msg라는 토픽명으로 publish함
  • topic_subscriber라는 이름의 node가 그 토픽을 ros_tutorial_sub라는 subscriber를 통해 받음
  • ros_tutorials_topic::MsgTutorial::msg 내에는 'time' type의 stamp, 'int32' type의 data가 들어있음

 

 

 

  • 아래 github에서 해당 내용에 대한 source code를 볼 수 있음

https://github.com/ROBOTIS-GIT/ros_tutorials/tree/master/ros_tutorials_topic

 

GitHub - ROBOTIS-GIT/ros_tutorials: ROS Tutorials for beginner

ROS Tutorials for beginner. Contribute to ROBOTIS-GIT/ros_tutorials development by creating an account on GitHub.

github.com

$ cd ~/catkin_ws/src
$ git clone https://github.com/ROBOTIS-GIT/ros_tutorials.git
$ cd ~/catkin_ws
$ catkin_make

 

- Service (Topic과 거의 비슷)

Service는 요청이 있을 때만 응답

 

1) Package 생성

$ cd ~/catkin_ws/src
$ catkin_create_pkg ros_tutorials_service message_generation std_msgs roscpp

 

2) Package.xml 수정

$ cd ros_tutorials_service
$ gedit package.xml
  • package.xml을 연 후 아래 코드 입력
<?xml version="1.0"?>
<package>
 <name>ros_tutorials_service</name>
 <version>0.1.0</version>
 <description>ROS turtorial package to learn the service</description>
 <license>Apache License 2.0</license>
 <author email="pyo@robotis.com">Yoonseok Pyo</author>
 <maintainer email="pyo@robotis.com">Yoonseok Pyo</maintainer>
 <url type="bugtracker">https://github.com/ROBOTIS-GIT/ros_tutorials/issues</url>
 <url type="repository">https://github.com/ROBOTIS-GIT/ros_tutorials.git</url>
 <url type="website">http://www.robotis.com</url>
 <buildtool_depend>catkin</buildtool_depend>
 <build_depend>roscpp</build_depend>
 <build_depend>std_msgs</build_depend>
 <build_depend>message_generation</build_depend>
 <run_depend>roscpp</run_depend>
 <run_depend>std_msgs</run_depend>
 <run_depend>message_runtime</run_depend>
 <export></export>
</package>

 

3) CMakeLists.txt 수정

$ gedit CMakeLists.txt
  • CMakeLists.txt를 연후 아래 코드 입력
cmake_minimum_required(VERSION 2.8.3)
project(ros_tutorials_service)
## 캐킨 빌드를 할 때 요구되는 구성요소 패키지이다.
## 의존성 패키지로 message_generation, std_msgs, roscpp이며 이 패키지들이 존재하지 않으면 빌드 도중에 에러가 난다.
find_package(catkin REQUIRED COMPONENTS message_generation std_msgs roscpp)
## 서비스 선언: SrvTutorial.srv
add_service_files(FILES SrvTutorial.srv)
## 의존하는 메시지를 설정하는 옵션이다.
## std_msgs가 설치되어 있지 않다면 빌드 도중에 에러가 난다.
generate_messages(DEPENDENCIES std_msgs)
## 캐킨 패키지 옵션으로 라이브러리, 캐킨 빌드 의존성, 시스템 의존 패키지를 기술한다.
catkin_package(
    LIBRARIES ros_tutorials_service
    CATKIN_DEPENDS std_msgs roscpp
)
## 인클루드 디렉터리를 설정한다.
include_directories(${catkin_INCLUDE_DIRS})
## service_server 노드에 대한 빌드 옵션이다.
## 실행 파일, 타겟 링크 라이브러리, 추가 의존성 등을 설정한다.
add_executable(service_server src/service_server.cpp)
add_dependencies(service_server ${${PROJECT_NAME}_EXPORTED_TARGETS}
${catkin_EXPORTED_TARGETS})
target_link_libraries(service_server ${catkin_LIBRARIES})
## service_client 노드에 대한 빌드 옵션이다.
add_executable(service_client src/service_client.cpp)
add_dependencies(service_client ${${PROJECT_NAME}_EXPORTED_TARGETS}
${catkin_EXPORTED_TARGETS})
target_link_libraries(service_client ${catkin_LIBRARIES})

 

 

4) Service 파일 작성

add_service_files(FILES SrvTutorial.srv)
  • CMakeLists.txt에 위와 같이 node에서 사용할 message인 SrvTutorial.srv를 build시 포함하도록 함

 

$ roscd ros_tutorials_service
$ mkdir srv
$ cd srv
$ gedit SrvTutorial.srv
  • SrvTutorial.srv에 아래 내용 작성
int64 a
int64 b
---
int64 result
  • int64는 메세지 형식
  • a, b는 서비스 요청 (service request). Service Client가 사용
  • result는 서비스 응답 (service response). Service Server가 사용
  • ---는 요청과 응답을 구분하는 구분자

 

5) Service Server Node 작성

add_executable(service_server src/service_server.cpp)
  • CMakeLists.txt에서 src 폴더에 있는 service_server.cpp 라는 파일을 build하여 service_server라는 execution file을 만들도록 했음

 

$ roscd ros_tutorials_service/src
$ gedit service_server.cpp
  • service_server.cpp 파일을 열고 아래 내용 입력
#include "ros/ros.h"
#include "ros_tutorials_service/SrvTutorial.h" 
// SrvTutorial 서비스 파일 헤더 (빌드후 위에서 작성한 srv 파일을 기준으로  자동 생성됨)

// 서비스 요청이 있을 경우, 아래의 처리를 수행한다
// 서비스 요청은 req, 서비스 응답은 res로 설정하였다
bool calculation(ros_tutorials_service::SrvTutorial::Request &req,
	ros_tutorials_service::SrvTutorial::Response &res)
{
// 서비스 요청시 받은 a와 b 값을 더하여 서비스 응답 값에 저장한다
res.result = req.a + req.b;

// 서비스 요청에 사용된 a, b 값의 표시 및 서비스 응답에 해당되는 result 값을 출력한다
ROS_INFO("request: x=%ld, y=%ld", (long int)req.a, (long int)req.b);
ROS_INFO("sending back response: %ld", (long int)res.result);
return true;	// 서비스 응답을 하는 부분. true를 return해야 client가 error없이 받았다고 인식함
}
int main(int argc, char **argv)		// 노드 메인 함수
{
ros::init(argc, argv, "service_server");	// 노드명 초기화
ros::NodeHandle nh;			// 노드 핸들 선언

// 서비스 서버 선언, ros_tutorials_service 패키지의 SrvTutorial 서비스 파일을 이용한
// 서비스 서버 ros_tutorials_service_server를 선언한다. 서비스명은 ros_tutorial_srv이며 서비스 요청이 있을 때
// calculation라는 함수를 실행하라는 설정이다
ros::ServiceServer ros_tutorials_service_server = nh.advertiseService("ros_tutorial_srv", calculation);
ROS_INFO("ready srv server!");
ros::spin(); // 서비스 요청이 있을 때까지 대기한다
return 0;
}

 

 

6) Service Client Node 작성

 

add_executable(service_client src/service_client.cpp)
  • CMakeLists.txt 파일에서 src 폴더에 있는 service_client.cpp 파일을 build하여 service_client라는 execution 파일을 만들게 했음

 

$ roscd ros_tutorials_service/src
$ gedit service_client.cpp
  • service_client_cpp 파일을 열어 아래 내용 입력
#include "ros/ros.h"
#include "ros_tutorials_service/SrvTutorial.h" // SrvTutorial 서비스 파일 헤더 (빌드후 자동 생성)
#include <cstdlib>	// atoll 함수 사용을 위한 라이브러리

int main(int argc, char **argv) {	// 노드 메인 함수
	ros::init(argc, argv, "service_client");	// 노드명 초기화
	if (argc != 3) {	// 입력값 오류 처리
		ROS_INFO("cmd : rosrun ros_tutorials_service service_client arg0 arg1");
		// service_client node 실행 후 서비스 요청으로 보낼 a, b를 받기 위해 arg0, arg1을 써놈 
		ROS_INFO("arg0: double number, arg1: double number");
		return 1;
		}
	ros::NodeHandle nh;		// ROS 시스템과 통신을 위한 노드 핸들 선언

	// 서비스 클라이언트 선언, ros_tutorials_service 패키지의 SrvTutorial 서비스 파일을 이용한
	// 서비스 클라이언트 ros_tutorials_service_client를 선언한다
	// 서비스명은 "ros_tutorial_srv"이다
	ros::ServiceClient ros_tutorials_service_client =
	nh.serviceClient<ros_tutorials_service::SrvTutorial>("ros_tutorial_srv");

	// srv라는 이름으로 SrvTutorial 서비스 파일을 이용하는 서비스를 선언한다
	ros_tutorials_service::SrvTutorial srv;

	// 서비스 요청 값으로 노드가 실행될 때 입력으로 사용된 매개변수를 각각의 a, b에 저장한다
	srv.request.a = atoll(argv[1]);
	srv.request.b = atoll(argv[2]);

	// 서비스를 요청하고, 요청이 받아들여졌을 경우, 응답 값을 표시한다
	if (ros_tutorials_service_client.call(srv)) {
		ROS_INFO("send srv, srv.Request.a and b: %ld, %ld", (long int)srv.request.a, (long int)srv.request.b);
		ROS_INFO("receive srv, srv.Response.result: %ld", (long int)srv.response.result);
		}
	else {
		ROS_ERROR("Failed to call service ros_tutorial_srv");
		return 1;
		}
	return 0;
}

 

 

7) ROS Node Build

$ cd ~/catkin_ws && catkin_make
  • catkin workspace로 이동 후 caktin build 실행

 

8) Service Server 실행

$ rosrun ros_tutorials_service service_server
  • roscore 실행 후 새 터미널 창을 열어 Service Server 실행
  • Service server는 service request가 있기 전까지 대기하도록 설정하였으므로 service request를 기다리게 된다

 

 

 

9) Service Client 실행

$ rosrun ros_tutorials_service service_client 2 3
[INFO] [1495726543.277216401]: send srv, srv.Request.a and b: 2, 3
[INFO] [1495726543.277258018]: receive srv, srv.Response.result: 5
  • Service Client 실행 시 입력해준 실행 매개변수 2, 3을 service request 값으로 전송되도록 설정하였었음
  • 2, 3은 각각 a, b값으로 service를 request하게 되고, 결괏값으로 2 + 3 = 5를 reponse값으로 전송받음
  • 해당 tutorial에서는 실행 parameter로 이를 사용하였으나, 실제 활용에서는 command나 계산되어야 할 값, trigger용 변수 등을 service request값으로 사용할 수도 있다

 

  • Service는 Topic과 달리 일회성 통신이므로 rqt_graph를 통해 확인할 수 없다 (한번 보내고 끝남)

 

 

  • [참고1] rosservice call 명령어 사용 방법
  • Service request를 위처럼 service client node 실행이 아닌 rosservice call 명령어를 통해 할 수 있다
$ rosservice call /ros_tutorial_srv 10 2

 

  • [참고2] GUI 도구인 Service Caller 사용 방법
  • rqt 실행 후 프로그램 메뉴에서 Plugins -> Service -> Service Caller를 선택

Service Caller

  • 사용할 Service 이름을 선택

  • a, b값을 타이핑 하여 설정한 후 좌측 상단의 'Call' 버튼을 눌러 response 확인

 

  • 하나의 Node는 복수의 Publisher, Subscriber, Service Server, Service Client 역할을 할 수 있다
ros::NodeHandle nh;

ros::Publisher topic_publisher = nh.advertise<ros_tutorials::MsgTutorial>("ros_tutorial_msg", 100);
ros::Subscriber topic_subscriber = nh.subscribe("ros_tutorial_msg", 100, msgCallback);
ros::ServiceServer service_server = nh.advertiseService("ros_tutorial_srv", calculation);
ros::ServiceClient service_client = nh.serviceClient<ros_tutorials::SrvTutorial>("ros_tutorial_srv");
  • 다만 위같이 node를 설정하면 혼자서만 값을 주고 받게 됨 (개념 설명만)

 

https://github.com/ROBOTIS-GIT/ros_tutorials/tree/master/ros_tutorials_service

 

GitHub - ROBOTIS-GIT/ros_tutorials: ROS Tutorials for beginner

ROS Tutorials for beginner. Contribute to ROBOTIS-GIT/ros_tutorials development by creating an account on GitHub.

github.com

  • Service 내용에 대한 Source Code

 

 

  - Parameter

  • roscore 실행 시 ros master, rosout(ros관련 log 기록), parameter 역할을 함
  • 그 중 parameter에 관한 내용

 

1) Parameter를 활용한 Node 작성

  • 앞서 작성한 Service Server와 Client node의 service_server.cpp 를 수정하여 service request로 입력된 a와 b를 단순히 더하는 것이 아닌 사칙연산을 할 수 있게끔 parameter 활용
  • 외부의 변수 parameter를 통해 내부의 process를 바꿈
$ roscd ros_tutorials_service/src
$ gedit service_server.cpp
  • service server 파일을 아래와 같이 수정
  • service client는 단순히 a, b를 보내는 역할만 하므로 변경하지 않음
#include "ros/ros.h"	// ROS 기본 헤더파일
#include "ros_tutorials_service/SrvTutorial.h" // SrvTutorial 서비스 파일 헤더 (빌드 후 자동 생성됨)
#define PLUS			1	// 덧셈
#define MINUS			2	// 뺄셈
#define MULTIPLICATION		3	// 곱셈
#define DIVISION		4	// 나눗셈

int g_operator = PLUS;	// 연산자는 덧셈을 기본으로 함
// 서비스 요청이 있을 경우, 아래의 처리를 수행한다
// 서비스 요청은 req, 서비스 응답은 res로 설정하였다

bool calculation(ros_tutorials_service::SrvTutorial::Request &req,
ros_tutorials_service::SrvTutorial::Response &res)
{
// 서비스 요청시 받은 a와 b 값을 파라미터 값(g_operator)에 따라 연산자를 달리한다.
// 계산한 후 서비스 응답 값에 저장한다
	switch(g_operator) {
			case PLUS:
				res.result = req.a + req.b; break;
			case MINUS:
				res.result = req.a - req.b; break;
			case MULTIPLICATION:
				res.result = req.a * req.b; break;
			case DIVISION:
				if(req.b == 0){
					res.result = 0; break;
					}
				else{
					res.result = req.a / req.b; break;
					}
			default:
		res.result = req.a + req.b; break;
		}
        
// 서비스 요청에 사용된 a, b값의 표시 및 서비스 응답에 해당되는 result 값을 출력한다
	ROS_INFO("request: x=%ld, y=%ld", (long int)req.a, (long int)req.b);
	ROS_INFO("sending back response: [%ld]", (long int)res.result);
	return true;
}
	
int main(int argc, char **argv)		// 노드 메인 함수
{
	ros::init(argc, argv, "service_server");	// 노드명 초기화
	ros::NodeHandle nh; // ROS 시스템과 통신을 위한 노드 핸들 선언
	nh.setParam("calculation_method", PLUS); // 매개변수 초기설정(1로 초기화)
    
	// 서비스 서버 선언, ros_tutorials_service 패키지의 SrvTutorial 서비스 파일을 이용한
	// 서비스 서버 service_server를 작성한다. 서비스명은 "ros_tutorial_srv"이며,
	// 서비스 요청이 있을 때, calculation라는 함수를 실행하라는 설정이다.
	ros::ServiceServer ros_tutorial_service_server = nh.advertiseService("ros_tutorial_srv", calculation);
	ROS_INFO("ready srv server!");
	ros::Rate r(10); // 10 hz
	while (1)
	{
		nh.getParam("calculation_method", g_operator);
        // 연산자를 parameter로부터 받은 값으로 변경한다
		ros::spinOnce();
        // 콜백함수 처리루틴
		r.sleep();
        // 루틴 반복을 위한 sleep 처리. 
	} 
return 0;
}

 

  • Parameter 관련 설정(setParam) 및 읽기(getParam) 사용법 주의

 

  • [참고] 파라미터로 사용 가능한 형태
  • 파라미터는 integers, floats, boolean, string, dictionaries, list 등으로 설정할 수 있다.
  • 간단히 예를 들자면, 1은 integers, 1.0은 floats, “Internet of Things”은 string, true는 boolean, [1,2,3]은 integers의 list, a: b, c: d는 dictionary이다.

 

2) Node Build 및 실행

$ cd ~/catkin_ws && catkin_make
$ rosrun ros_tutorials_service service_server
  • catkin build 후 service server node 실행

 

3) Parameter 목록 보기

$ rosparam list
  • 현재 ROS 네트워크에 사용된 파라미터의 목록 확인
  • 아래와 같은 결과가 뜸
/calculation_method
/rosdistro
/rosversion
/run_id
  • /calculation_method가 위에서 사용한 parameter

 

 

4) Parameter 사용 예

$ rosservice call /ros_tutorial_srv 10 5 → 사칙연산의 변수 a, b 입력
result: 15	 			 → 디폴트 사칙연산인 덧셈 결괏값
$ rosparam set /calculation_method 2 	 → 뺄셈
$ rosservice call /ros_tutorial_srv 10 5
result: 5 
$ rosparam set /calculation_method 3 	 → 곱셈
$ rosservice call /ros_tutorial_srv 10 5
result: 50 
$ rosparam set /calculation_method 4 	 → 나눗셈
$ rosservice call /ros_tutorial_srv 10 5
result: 2
  • 같은 service request를 하며 parameter를 변경하여 service response가 달라짐을 확인
  • Parameter는 Node 외부에서 node의 흐름이나 설정, 처리 등을 바꿀 수 있다 (매우 유용한 기능이므로 숙지 필요)

 

https://github.com/ROBOTIS-GIT/ros_tutorials/tree/master/ros_tutorials_parameter

 

GitHub - ROBOTIS-GIT/ros_tutorials: ROS Tutorials for beginner

ROS Tutorials for beginner. Contribute to ROBOTIS-GIT/ros_tutorials development by creating an account on GitHub.

github.com

  • Parameter에 관한 Source file

 

- roslaunch 사용법

  • rosrun : 하나의 node만을 실행
  • roslaunch : 다수의 node 실행 가능
  • roslaunch는 node 실행뿐만 아니라 node 실행시 package의 parameter나 node 이름 변경, node namespace 설정, ROS_ROOT 및 ROS_PACKAGE_PATH 설정, 환경 변수 변경 등의 option을 붙일 수 있는 ROS 명령어이다.
$ roslaunch [패키지명] [roslaunch 파일]
  • tag별 옵션을 제공하는 XML기반의 '.launch' file을 실행하며 해당 file은 package folder내 'launch' folder 안에 있어야 한다

launch file 예시

 

1) roslaunch의 활용

  • 앞서 작성한 topic_publisher와 topic_subscriber node의 이름을 바꿔 실행
$ roscd ros_tutorials_topic
$ mkdir launch
$ cd launch
$ gedit union.launch
  • ros_tutorials_topic package directory로 이동 후 launch directory 생성 후 그곳으로 이동하여 launch file 생성
  • union.launch는 위의 topic 관련 github source code에 있는 launch file

 

<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>
  • union.launch 파일
  • <launch> 태그 안에는 roslaunch 명령어로 노드를 실행할 때 필요한 태그들이 기술됨
  • <node>는 roslaunch로 실행할 노드를 기술. 옵션으로는 pkg, type, name이 있다.
    • pkg : 패키지의 이름
    • type : 실제 실행할 노드의 이름(노드명)
    • name : 위 type에 해당하는 노드가 실행될 때 붙여지는 이름(실행명), 일반적으로는 type과 같게 설정하지만 필요에 따라 실행할 때 이름을 변경하도록 설정할 수 있다.
  • 위의 경우 각 subscriber와 publisher node의 구분을 위해 이름을 다르게 함

 

$ roslaunch ros_tutorials_topic union.launch --screen
  • union.launch 파일 실행
  • --screen은 해당 터미널에 실행되는 모든 node들의 출력들이 표시되게 하는 option

 

$ rosnode list
  • 실행 node확인
/topic_publisher1
/topic_publisher2
/topic_subscriber1
/topic_subscriber2
/rosout
  • 확인 결과 4개의 node가 정상적으로 실행되고 이름도 의도한데로 바뀜

 

  • 그런데 rqt로 확인한 결과 subscriber node가 두 publisher node의 message를 모두 subscribe 하고 있음
  • launch file에서 단순히 node의 이름만을 변경하고 사용 message의 이름을 변경하지 않아 생기는 문제
  • 다른 roslaunch namespace tag를 사용하여 해결 가능

 

$ roscd ros_tutorials_service/launch
$ gedit union.launch
  • union.launch 파일을 아래와 같이 수정
<launch>
 <group ns="ns1">
 <node pkg="ros_tutorials_topic" type="topic_publisher" name="topic_publisher"/>
 <node pkg="ros_tutorials_topic" type="topic_subscriber" name="topic_subscriber"/>
 </group>
 <group ns="ns2">
 <node pkg="ros_tutorials_topic" type="topic_publisher" name="topic_publisher"/>
 <node pkg="ros_tutorials_topic" type="topic_subscriber" name="topic_subscriber"/>
 </group>
</launch>
  • <group>은 실행되는 node를 group으로 묶을 때 사용
  • 위의 경우 'ns' option (name space)을 통해 그룹의 이름을 ns1, ns2로 지칭함
  • 그룹에 속한 node의 이름과 message 등도 모두 ns로 지정한 이름에 포함됨

 

  • Topic과 node의 이름이 변경됨

 

<launch>
 <arg name="update_ period" default="10" />
 <param name="timing" value="$(arg update_ period)"/>
</launch>
  • <arg>를 통해 launch file 내부에 "update_period" 변수를 정의 (기본값 : 10)
$ roslaunch my_package my_package.launch update_ period:=30
  • roslaunch를 통해 외부에서 parameter 값을 변경 (주기)

 

 

https://github.com/ROBOTIS-GIT/ros_tutorials

 

GitHub - ROBOTIS-GIT/ros_tutorials: ROS Tutorials for beginner

ROS Tutorials for beginner. Contribute to ROBOTIS-GIT/ros_tutorials development by creating an account on GitHub.

github.com

  • 이번 강좌의 repository

 

 

 


https://www.youtube.com/watch?v=iGdQHi_wL1Y&list=PLRG6WP3c31_VIFtFAxSke2NG_DumVZPgw&index=9 

https://changun516.tistory.com/134

 

[ROS] param vs rosparam

| param과 rosparam 차이점 1. param - Parameter Server에서 설정할 파라미터를 정의 - value의 파라미터 설정을 txt file, bin file, command 속성으로 지정하여 매개 변수의 값을 설정할 수 있음 * value는 string, int, bo

changun516.tistory.com

https://enssionaut.com/board_robotics/974

 

로봇 - ROS(Robot Operating System) 개념과 활용 - 8. roslaunch 사용과 launch 파일 작성하기

저번에 USB 카메라를 이용하면서 usb_cam-test.launch 파일을 실행시켜 보았습니다. usb_cam-test.launch 파일을 실행시키면 USB 카메라와 직접적으로 상호작용하는 '/usb_cam' 노드와 '/usb_cam/image_raw' 토픽을 받

enssionaut.com

https://velog.io/@717lumos/roslaunch%EC%9D%98-%EC%82%AC%EC%9A%A9%EB%B2%95-%EB%B0%8F-XML

 

[ROS] roslaunch의 사용법 및 XML

ROS roslaunch 사용법 및 XML 작성법

velog.io

https://changun516.tistory.com/134