ロボットシステム学2016第13回
Mon Jan 16 19:24:06 JST 2017 (modified: Fri Nov 29 17:15:49 JST 2019)
views: 1092, 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点。一捻りあれば満点に近づくということで