ROS勉強会 - 林原研究室 
<入門編> 
2014年9月5日  
千葉工業大学 工学部 4年  
ロボット設計・制御研究室 前川大輝
目次 
1.ROSとは 
2.ディストリビューション 
3.ROSの歴史 
4.便利なパッケージを動かしてみよう 
5.本日の学習範囲 
6.通信の基本モデル 
7.ROSのノードについて理解する 
8.ROSのトピックを理解する 
9.RVizで図形を可視化しよう
ROS(Robot Operating System)とは 
■オープンソースで提供されるロボット向けのメタ・オペレーティングシステム 
■ロボット制御用のミドルウェア 
 → ソースをコンパイルするためのビルドシステム 
 → プロセス間通信のための通信ライブラリ 
■ロボット工学分野の研究・開発におけるコードの”再利用”を 
 支援することが目的 
ROS = 通信 + ツール群 + 機能群 + エコシステム
PR2のデモ
オドメトリ無しSLAM
ディストリビューション 
■ー年周期のリリース(五月までHydro) 
■ーつのリリースの開発(Indigo) 
■二つのリリースのサポート
ROSの歴史 
■2007年 Stanford大学のAI Labが開発 
■2008年 WillowGarageが開発を引き継ぎ 
■2013年2月からOSRF(Open Source Robotics Foundation)が開発
便利なパッケージを使ってみよう 
■オドメトリフリーなSLAMをとりあえず動かしてみよう 
理解に必要な知識は後で解説
■パッケージのインストール 
$ sudo apt-get install ros-hydro-hector-slam 
■バグファイル(ログ)のダウンロード 
$ wget http://tu-darmstadt-ros-pkg. 
googlecode.com/files/Team_Hector_MappingBox_RoboCup_2 
011_Rescue_Arena.bag 
■hector_slamの起動 
$ roslaunch hector_slam_launch tutorial.launch 
■バグファイルの再生 
$ rosbag play 
Team_Hector_MappingBox_RoboCup_2011_Rescue_Arena.bag 
--clock 
■地図の保存 
$ rostopic pub syscommand std_msgs/String "savegeotiff"
シミュレータへの応用事例
本日の学習範囲 
Q : 何から勉強するの? 
A : まずは本家のチュートリアルをこなしましょう
本家チュートリアル 
初級 
1.ROS環境のインストールとセットアップ 
2.ROSのファイルシステムを学ぶ 
3.ROSパッケージを作る 
4.ROSのパッケージをビルドする 
5.ROSのノードを理解する 
6.ROSのトピックを理解する 
7.ROSのサービスとパラメータを理解する 
8.rqt_consoleとroslaunchを使う 
9.ROSでrosedを使ってファイルを編集する 
10.ROSのメッセージやサービスなどを作る 
11.シンプルなパブリッシャとサブスクライバを書く 
12.データを記録し、リプレイをする 
中級 
他のライブラリのチュートリアル 
その他
初級 
1.ROS環境のインストールとセットアップ 
2.ROSのファイルシステムを学ぶ 
3.ROSパッケージを作る 
4.ROSのパッケージをビルドする 
5.ROSのノードを理解する 
6.ROSのトピックを理解する 
7.ROSのサービスとパラメータを理解する 
8.rqt_consoleとroslaunchを使う 
9.ROSでrosedを使ってファイルを編集する 
10.ROSのメッセージやサービスなどを作る 
11.シンプルなパブリッシャとサブスクライバを書く 
12.データを記録し、リプレイをする 
中級 
他のライブラリのチュートリアル 
その他 
本日の学習範囲 
本家チュートリアル
通信の基本モデル
■ソフトウェアの単位: ノード 
■ロボットのセンサやアクチュエータ等を別々のノードとして定義 
 → それを組み合わせ分散システムを構築 
Node A 
Node B 
Node C
■出版-購読型のメッセージング 
■異なるプログラミング言語で記述されたノードでもやりとりが可能 
Node A 
Node C 
Publish 
Subscribe 
Publish 
TopicA 
Node B 
Subscriber 
Publisher Publisher
■サービス (リモート関数呼び出し) 
■利用側(多くはノード)からリクエストを受け取ると特定の処理を行うもの 
Arguments 
Client Service 
Return Values
■パラメータ 
■トピック以外のデータを送受信するための仕組み 
■パラメータサーバがデータを保持 
 → 他のノードからの変更は通知される
■マスター 
■ノードやトピックの管理を行う 
■roscoreというプロセスにより提供される
■パッケージ 
■機能毎に分類されたノードやライブラリの単位のこと 
■パッケージを管理するための便利なコマンドが多数提供されている 
■ロボット用のオープンソースパッケージが多数公開されている
ROSのノードについて理解する
■ROSを使用する際に一番初めにroscoreを起動する 
$ roscore
■rosrunを用いてパッケージに含まれるノードを起動 
$ rosrun turtlesim turtlesim_node
■ノードの一覧を表示 
$ rosnode list 
/rosout 
/turtlesim 
Ctrl - Cでノードを停止
■リマップでコマンドラインから名前を変更 
$ rosrun turtlesim turtlesim_node __name := 
my_turtle 
rosnode list 
/rosout 
/my_turtle
■ノードが起動しているか確認 
$ rosnode ping my_turtle 
rosnode: node is [/my_turtle] 
pinging /my_turtle with a timeout of 3.0s 
xmlrpc reply from http://daikimaekawa-ThinkPad-X230:58887/ 
time=0.523806ms 
xmlrpc reply from http://daikimaekawa-ThinkPad-X230:58887/ 
time=1.019001ms 
xmlrpc reply from http://daikimaekawa-ThinkPad-X230:58887/ 
time=1.125097ms
ROSのトピックを理解する
■キーボードによる亀の操作 
$ rosrun turtlesim turtle_teleop_key
■システムの進行状況・挙動を示すグラフの生成 
$ rqt_graph 
ROSのノードやトピックがハイライトされる
■rostopicはトピックの詳細を調べるコマンド 
$ rostopic echo /turtle1/cmd_vel 
linear: 
x: 0.0 
y: 0.0 
z: 0.0 
angular: 
x: 0.0 
y: 0.0 
z: 2.0 
--- 
linear: 
x: 2.0 
y: 0.0 
z: 0.0 
angular: 
x: 0.0 
y: 0.0 
z: 0.0 
---
■rostopicが /turtle1/cmd_velを購読していることを 
 確認してみよう 
$rqt_graph
■配信者と購読者が通信するためには同じ型のメッセージ 
 を送受信する必要がある 
■トピックの型は配信されるメッセージの型により定義される 
■rostopicを使って簡単に調べることが可能
■配信-購読されているトピックとその型の情報を調べる 
$ rostopic list -v 
Published topics: 
* /turtle1/color_sensor [turtlesim/Color] 1 publisher 
* /turtle1/cmd_vel [geometry_msgs/Twist] 1 publisher 
* /rosout [rosgraph_msgs/Log] 3 publishers 
* /rosout_agg [rosgraph_msgs/Log] 1 publisher 
* /turtle1/pose [turtlesim/Pose] 1 publisher 
Subscribed topics: 
* /turtle1/cmd_vel [geometry_msgs/Twist] 2 subscribers 
* /rosout [rosgraph_msgs/Log] 1 subscriber
■rostopic typeで特定のトピックのメッセージ型を調べる 
$ rostopic type /turtle1/cmd_vel 
geometry_msgs/Twist
■rosmsgを使用してメッセージの詳細を調べる 
$ rosmsg show geometry_msgs/Twist 
geometry_msgs/Vector3 linear 
float64 x 
float64 y 
float64 z 
geometry_msgs/Vector3 angular 
float64 x 
float64 y 
float64 z
■rostopic pubはトピックへデータを配信します 
■turtlesimを直線速度2.0, 角速度1.8で移動させる 
$ rostopic pub -1 
/turtle1/cmd_vel 
geometry_msgs/Twist '[2.0, 0.0, 0.0]' '[0.0, 0.0, 1.8]' 
rostopic pub [topic] [msg_type] [args]
■亀は動き続けるために定期的な1Hzのコマンドが必要 
$ rostopic pub 
/turtle1/cmd_vel geometry_msgs/Twist -r 1 
-- '[2.0, 0.0, 0.0]' '[0.0, 0.0, 1.8]'
■何が起こっているかはrqt_graphでも可視化できる 
■rostopic pub node と rostopic echo nodeが通信 
$ rqt_graph
■rostopic hzは配信されたデータの更新頻度を調べる 
■/turtle1/poseを購読して, turtlesim_nodeの速さがど 
 の程度か見てみよう 
$ rostopic hz /turtle1/pose 
subscribed to [/turtle1/pose] 
average rate: 62.489 
データの更新頻度は60Hz 
min: 0.016s max: 0.016s std dev: 0.00011s window: 62 
average rate: 62.491 
min: 0.016s max: 0.016s std dev: 0.00009s window: 125 
average rate: 62.496 
min: 0.016s max: 0.016s std dev: 0.00009s window: 187
■コマンドを組み合わせて便利に使える 
■rostopic type と rosmsg showを結合して使ってみよう 
 → 普通にパイプが使える 
$ rostopic type /turtle1/cmd_vel | rosmsg show 
geometry_msgs/Vector3 linear 
float64 x 
float64 y 
float64 z 
geometry_msgs/Vector3 angular 
float64 x 
float64 y 
float64 z
■rqt_plotはトピックで配信されている 
データの時間図を表示する 
$ rqt_plot 任意のトピックを追加
■/turtle1/pose/xと/turtle1/pose/yを可視化
■-ボタンで非表示にできる 
■/turtle1/pose/thetaを追加
■rosservice listでアクティブなサービスの情報を表示 
$ rosservice list 
/clear 
/kill 
/reset 
/rosout/get_loggers 
/rosout/set_logger_level 
/spawn 
/turtle1/set_pen 
/turtle1/teleport_absolute 
/turtle1/teleport_relative 
/turtlesim/get_loggers 
/turtlesim/set_logger_level
■rosservice type でサービスの型を表示します 
$ rosservice type clear 
std_srvs/Empty 
リクエストの作成にデータを送らない 
レスポンスの受け取りにデータを受け取らない
■rosservice callでサービスを呼び出す 
■turtlesimをクリアしよう 
$ rosservice call clear
■サービスが引数をとる場合を考えましょう 
■spawnサービスは新しい亀を誕生させる 
$ rosservice type spawn | rossrv show 
float32 x 
float32 y 
float32 theta 
string name 
--- 
string name
■位置と向きを与えて新しい亀を誕生させよう 
 → 名前の指定は任意 
$ rosservice call spawn 2 2 0.2 “” 
name: turtle2 
作成した亀の名前を返す
■rosparamはROSパラメータサーバを用いてデータの 
 蓄積や操作を実現 
$ rosparam list 
/background_b 
/background_g 
/background_r 
/rosdistro 
/roslaunch/uris/host_daikimaekawa_thinkpad_x230__57324 
/rosversion 
/run_id
■rosparam setでパラメータの値を変える 
$ rosparam set /background_r 255 
$ rosservice call clear
■rosparam getでパラメータの値を取得する 
$ rosparam get /background_r 
255
■全てのパラメータサーバの中身を見る 
$ rosparam get / 
background_b: 255 
background_g: 86 
background_r: 255 
rosdistro: 'hydro 
' 
roslaunch: 
uris: {host_daikimaekawa_thinkpad_x230__57324: 
'http://daikimaekawa-ThinkPad-X230:57324/'} 
rosversion: '1.10.2 
' 
run_id: 2ec6f1ae-be3f-11e3-986c-b8763fd266b5
■全てのパラメータをファイルに書き出す 
$ rosparam dump params.yaml 
■yamlファイルをcopyというネームスペース 
の中に読み込む 
$ rosparam load params.yaml copy 
■rosparam getで中身を確認する 
$ rosparam get copy/background_b 
255
RVizで図形を可視化しよう 
■通信システムを大まかに理解するためのサンプル 
■RVizでデータを3次元マップ上に可視化 
■トピックを送信するプログラムを書いてみよう
■ROSのワークスペースを作成(catkin) 
$ mkdir -p ~/catkin_ws/src 
$ cd ~/catkin_ws/src 
$ catkin_init_workspace 
$ cd ~/catkin_ws 
$ catkin_make 
$ echo “source ~/catkin_ws/devel/setup.bash” 
>> ~/.bashrc 
$ source ~/.bashrc
■パッケージ作成 
$ cd ~/catkin_ws/src 
$ catkin_create_pkg marker_publisher roscpp 
visualization_msgs
■ノードを作成 
$ roscd marker_publisher/src 
$ vi marker_publisher.cpp
■使用するヘッダファイルのインクルード 
#include <cmath> 
#include <ros/ros.h> 
#include <visualization_msgs/Marker.h>
■初期設定 
#define DEFAULT_RATE 20 
int main(int argc, char *argv[]){ 
ros::init(argc, argv, “test”); 
ros::NodeHandle n; 
ros::Publisher marker_pub = 
n.advertise<visualization_msgs::Marker>(“visualiz 
ation_marker”, 10); 
・・・ 
}
■初期設定 
int main(int argc, char *argv[]){ 
・・・ 
 visualization_msgs::Marker line_strip; 
line_strip.header.farme_id = “practice”; 
line_strip.ns = “practice”; 
line_strip.id = 1; 
line_strip.type = 
visualization_msgs::Marker::LINE_STRIP; 
line_strip.action = 
visualization_msgs::Marker::ADD; 
・・・ 
}
■初期設定 
int main(int argc, char *argv[]){ 
・・・ 
 line_strip.scale.x = 0.1; 
line_strip.color.b = 1.0; 
line_strip.color.a = 1.0; 
float phai = 0.0; 
n.setParam(“/rate”, DEFAULT_RATE); 
・・・ 
}
■図形を作成 
int main(int argc, char *argv[]){ 
・・・ 
for(int i=0; i <= 10; i++){ 
const float radius = i % 2 ? 6.0 : 3.0; 
const float theta = 
(72.0 * (i/2) + (i%2) * 36.0) * M_PI / 180.0; 
geometry_msgs::Point vertex; 
vertex.x = radius * cos(theta); 
vertex.y = radius * sin(theta); 
line_strip.points.push_back(vertex); 
} 
・・・ 
}
■図形の回転 
int main(int argc, char *argv[]){ 
・・・ 
 while(ros::ok()){ 
int val = DEFAULT_RATE; 
if(n.getParam(“/rate”, val)){ 
std::cout << “val = ” << val << std::endl; 
} 
ros::Rate r(val); 
line_strip.header.stamp = ros::Time::now(); 
line_strip.pose.orientation.z = sin(phai / 2); 
line_strip.pose.orientation.w = cos(phai / 2); 
・・・ 
} 
return 0; 
}
■図形の回転 
while(ros::ok){ 
・・・ 
 marker_pub.publish(line_strip); 
phai += 0.05; 
if(phai > 2 * M_PI) phai -= 2 * M_PI; 
r.sleep(); 
}
■CMakeLists.txtを編集 
$ rosed marker_publisher CMakeLists.txt
■CMakeLists.txtを編集 
・・・ 
add_executable(marker_publisher_node 
src/marker_publisher.cpp 
) 
target_link_libraries(marker_publisher_node 
${catkin_LIBRARIES} 
) 
・・・
■パッケージをビルド 
$ cd ~/catkin_ws 
$ catkin_make
■ノードを起動 
$ rosrun marker_publisher marker_publisher_node 
■rostopic echoでframe_idを確認 
$ rostopic echo /visualization_marker 
・・・ 
 frame_id: practice 
 ・・・ 
line_strip.header.frame_id = “practice”
■rvizで図形を可視化
■rqt_graphでノード間通信を可視化 
$ rqt_graph
■図形の回転速度を変更 
$ rosparam set /rate 100
■rosbagでトピックを記録 
$ rosbag record /visualization_marker 
■marker_publisher_nodeを停止 
$ Ctrl - C 
■rosbagでバグファイルを再生 
$ rosbag play *.bag 
rosbagはデバックの強い味方
ご清聴ありがとうございました。

ROS Tutorial 02 - CIT