CIT自律ロボット研究室

千葉工業大学 先進工学部 未来ロボティクス学科 上田隆一研究室

お知らせ: 本研究室所属の3年生チームがAWS Robot Delivery Challengeで優勝しました / 

ロボットシステム学2016第13回

Mon Jan 16 19:24:06 JST 2017 (modified: Fri Nov 29 17:15:49 JST 2019)
views: 155, keywords:

  このエントリーをはてなブックマークに追加 
   

ロボットシステム学

第13回

上田 隆一

2017年1月18日\@千葉工業大学

本日の内容

  • ROS
    • ROSのインストールが終わった状態からスタート
    • 講義で扱うのはとりあえず触ってみる程度
      • 講義を通じて得たLinuxの知識があれば十分独学が可能

動作確認

  • $ roscore
    • ROSのバックにいるプログラムが立ち上がる
    • Ctrl+cで出る
$ roscore
(略)
started roslaunch server http://localhost:39310/
ros_comm version 1.12.6

SUMMARY
========

PARAMETERS
* /rosdistro: kinetic
* /rosversion: 1.12.6

NODES

auto-starting new master
process[master]: started with pid [1439]
ROS_MASTER_URI=http://localhost:11311/

setting /run_id to b749a100-d0dc-11e5-a506-b827eb17cb96
process[rosout-1]: started with pid [1452]
started core service [/rosout]

ROSのノード

  • プログラムのプロセス一つ一つが「ノード」と呼ばれる
  • ノードの例
    • cv_cameraとmjpeg_serverを立ち上げる(roscoreは立ち上げておく)
    • $ rosrun cv_camera cv_camera_node 
      $ rosrun mjpeg_server mjpeg_server 
    • ノードの確認
      $ rosnode list
      /cv_camera
      /mjpeg_server
      /rosout
    • ディレクトリのように管理されている

トピック・メッセージ

  • 今度はrostopic listと打ってみる
  • データをやり取りする口(トピック)が表示される
  • $ rostopic list
    /cv_camera/camera_info
    /cv_camera/image_raw
    /rosout
    /rosout_agg
  • トピックからデータを取り出す(先週もやりました)
  • $ rostopic echo /cv_camera/image_raw
    • このデータは「メッセージ」と呼ばれる

パブリッシャ・ サブスクライバ

  • 各ノードがトピックを通じてメッセージを融通することで全体として仕事を行う
  • mjpeg_serverは/cv_camera/image_rawからカメラ画像を取得して、ブラウザに画像を配信
  • データを出す側がパブリッシャ
  • データを受け取る側がサブスクライバ
  • この構造でサブスクライバ側の柔軟な組み換えが可能に
    • ブラウザに配信するノード、顔検出をするノード、mp4に変換するノード・・・

ROSプログラミングの準備

  • パブリッシャ、サブスクライバを作ってみましょう
  • その前に・・・
  • 「ワークスペース」(作業場)を作る
  • $ cd
    $ mkdir -p catkin_ws/src
    $ cd ~/catkin_ws/src
    $ catkin_init_workspace 
    Creating symlink "/home/ubuntu/catkin_ws/src/CMakeLists.txt" pointing to "/opt/ros/kinetic/share/catkin/cmake/toplevel.cmake"
    $ ls
    CMakeLists.txt

  • .bashrcの末尾に以下を記述
source /opt/ros/kinetic/setup.bash #これは元からある
source ~/catkin_ws/devel/setup.bash #ここから3行追加
export ROS_MASTER_URI=http://localhost:11311
export ROS_HOSTNAME=localhost
  • 環境のビルド
$ cd ~/catkin_ws
$ catkin_make
$ source ~/.bashrc
  • 確認
    • ROS_PACKAGE_PATHにcatkin_ws/srcがセットされているはず
$ echo $ROS_PACKAGE_PATH
/home/ubuntu/catkin_ws/src:/opt/ros/kinetic/share

パッケージを作る

  • パッケージ: いくつかのノードを含んだ一単位
  • パッケージの生成
    • catkin_create_pkg <作るパッケージの名前> [使用するライブラリ...]
    • rospy: Pythonでノードを作るときに使用
    • パッケージを作ったら下にscriptsというディレクトリを作成
      • ここにノードとなるプログラムを置く
$ cd ~/catkin_ws/src
$ catkin_create_pkg mypkg rospy
 Created file mypkg/package.xml
 Created file mypkg/CMakeLists.txt
 Created folder mypkg/src
 Successfully created files in /home/ubuntu/catkin_ws/src/mypkg. Please adjust the values in package.xml.
$ cd mypkg/
$ mkdir scripts
$ cd scripts/

パブリッシャを作る

  • 次のようなプログラム(count.py)を書いてみましょう
  • ノード名が「count」、パブリッシャが「count_up」
  • rospy.Publisherを作って定期的にデータを投げる
    • count_upというトピックに、型はInt32で(バッファとなるキューのサイズは1)
#!/usr/bin/env python
import rospy
from std_msgs.msg import Int32

if __name__ == '__main__': 
    rospy.init_node('count')
    pub = rospy.Publisher('count_up', Int32, queue_size=1)
    rate = rospy.Rate(10)
    n = 0
    while not rospy.is_shutdown():
        n += 1
        pub.publish(n)
        rate.sleep()

ノードの実行

$ rosrun mypkg count.py
  • rosnode listとrostopic listでノードとトピックの確認を
  • 次にrostopic echoでcount_upからデータを取り出してみましょう
$ rostopic echo /count_up 
data: 1430
---
data: 1431
---
data: 1432
---
data: 1433
...

サブスクライバを作る

  • 次のようなtwice.pyを作る
  • rospy.Subscriberを使う
    • count_upという名前のトピックを購読する
    • 型はInt32
    • データを受け取ったときにcbという関数で処理
      • コールバック関数
#!/usr/bin/env python
import rospy
from std_msgs.msg import Int32

def cb(message):
    rospy.loginfo(message.data*2)

if __name__ == '__main__': 
    rospy.init_node('twice')
    sub = rospy.Subscriber('count_up', Int32, cb) 
    rospy.spin()

twice.pyの実行

  • roscore、rosrun mypkg count.pyを事前に実行しておく
  • 二倍になった数字が端末上に表示される
    • 非同期なので欠ける可能性があることに注意
    • 途中で切ってまた立ち上げても再開
$ rosrun mypkg twice.py 
[INFO] [1484659840.762425]: 4
[INFO] [1484659840.862150]: 6
[INFO] [1484659840.961791]: 8
[INFO] [1484659841.062162]: 10
...

パブリッシャと サブスクライバの同居

  • twice.pyにパブリッシャを追加
#!/usr/bin/env python
import rospy
from std_msgs.msg import Int32

n = 0

def cb(message):
    global n
    n = message.data*2

if __name__ == '__main__': 
    rospy.init_node('twice')
    sub = rospy.Subscriber('count_up', Int32, cb) 
    pub = rospy.Publisher('twice', Int32, queue_size=1) 
    rate = rospy.Rate(10)
    while not rospy.is_shutdown():
        pub.publish(n)
        rate.sleep()

実行

  • ノードを立ち上げてrostopic echo /twiceでトピックとしてデータを得る
$ rostopic echo /twice
data: 1050
---
data: 1052
---
data: 1054
---
data: 1056
...

 

その他

  • package.xml
    • パッケージの情報が書かれる
    • メンテナの名前、ライセンス、他のパッケージの依存関係等、配布に必要な情報
  • CMakeLists.txt
    • ビルド情報
    • 自分で型を作る、C++でノードを作る等、講義の内容より複雑なことをするときには手を入れる必要がある
  • 参考: 小倉: ROSではじめるロボットプログラミング, 工学社, 2015. 

課題

  • ROSで何か作る
  • あとは課題1と同じ提出方法で
    • GitHubにパッケージを置く
    • YouTube等に実行例
    • メールで連絡(件名: 課題2 <学籍番号> <氏名>)
  • 締め切り2/8
  • 満点20点+α
    • 体裁を整えて今日の内容を置いてくれたら15点。一捻りあれば満点に近づくということで