2016年10月31日月曜日

[Book]Programming Robots with ROS Chapter4: Service を読みながらServiceを試した。後編

前回の続き。

前編で下準備が完了したので、後半は実装のお話し。

使用したソースコードはGitHubに後でおく予定。


Implementing a Service

service_server.py

callbackで指定された文の単語数を返す。

注意点

- WordCountResponseとWordCountをimportする。

- ノードを活かしておくためにrospy.spin()使う。手っ取りばやい。


Checking That Everything Works as Expected


作成したノードを実行してみる。

$ rosrun service_sample service_server.py

service_sampleの部分はcatkin_create_pkgで指定したパッケージ名になります。

ちゃんと動いてるか確認するのに、以下を実行。

$ rosservice list

これで/word_countが表示されることを確認。


さらに、追加で情報が欲しい場合は、以下を実行。

$ rosservice info word_count

これでノード名や型、引数等の情報が表示される。



Other Ways of Returning Values from a Service

戻り値、いろんな形式で指定できますよ、の説明。3通り。省略


Using a Service


server側の実装はできたので、コマンドラインから以下で確認することも可能。

$ rosservice call word_count 'one two three'
count: 3


でも通常は別のノードから呼び出すので、client側のサンプル作りましょー。


service_client.py

ポイント

-  rospy.wait_for_service('word_count')でサービスが開始するのを待つ。

 サービスが開始する前の呼び出すと、exceptionで落ちる。

- word_counter = rospy.ServiceProxy('word_count', WordCount)で指定したword_counterに
 引数(文字数確認対象の文字列)を指定して呼び出す。


Checking That Everithing Works as Expected


コマンドラインから動作確認。

$ rosrun service_sample service_client.py these are some words
these are some words -> 4

注意点

何かしらサーバーに問題があると永遠にclientが待ち続けることがあるよ、と。(まじか。。)


Other Ways to Call Service

- 戻り値2個のケース。戻り値を受ける変数がc, iとかだと、srvで定義した順に戻り値が返る。

例: c, i = word_count(words, 3) だと、count, ignoreの順。

- serviceを使うのに、WordCountRequestを使って以下のように書くこともできる。

  request = WordCountRequest('one two three', 3)
  count, ignored = word_counter(request)

この書き方をする場合は、WordCountRequestをimportするのを忘れないこと。

- 引数にword_counter(words='one two three')みたいにキーワードを指定することもできます。
 
ただし、この書き方の場合指定しない引数は不定とかになるのをちゃんと注意しましょうね。


Summary

- serviceの使い方、実装の仕方を一通り確認しました。

- 全部はカバーしてないのでwikiを見ましょうね。http://wiki.ros.org/Services?distro=indigo

- 同期の返事が必要なとき、とか必要なときに使いましょう。
 
 基本replyはすぐ返ることを想定しているので、長時間replyにかかる場合はChapter5の
  action を使ったほうがいいかもしれません。


=============================================================================
ということで、一通りServiceについて終了。
どういうときに使うかは使いながら覚えていこうと思います。


せっかくだからactionについても勉強してみる。近々。


[Book]Programming Robots with ROS Chapter4: Service を読みながらServiceを試した。前編

こんにちは。

Topicばっかり使ってServiceの勉強してないことに気づいたので、せっかくなのでProgramming 
Robots with ROSのChapter4を読みながら動かしてみることにしました。

ちなみにこれ読む前は小倉さんの本で”同期で何かやりたいときに使う何か”くらいの理解でした。
まー読んだ後もあんまり理解は変わってませんが。。笑

まえがき

- あるノードが別のノードのfunctionを呼ぶ場合に使う。

- input/outputを定義するよ

- ユースケースとしては、センサをONしたり、カメラで高解像度の写真を撮ったりすることを想定

既存のサービスも多数ありますが、あえて中身を理解するために今回は独自のserviceを作る、とのこと。

Defining a Service

service-definition fileを自分で定義してみましょう、という段落になります。

message-definition file(Topicで使用する定義)と似ているのですが、
Input/Outputの定義がある点が異なります。

今回文字列から単語数をカウントするサービスですので、定義するサービスは以下とします。

WordCount.srv

string words
---
uint32 count

"---"は入力と出力の間に書きます。

作ったsrvファイルを適切なディレクトリに配置したら、catkin_makeを再度やる必要があります。
この辺は自分でmsg追加したときと同じ手順ですね。

CMakeLists..txtとpackage.xmlを一部修正する必要があります。


CMakeLists.txt

  1.  find_packageにmessage_generationを追加
  2.  add_service_filesにWordCount.srvを追加
  3.  generate_messagesを有効化

package.xml

以下を追加。コメントアウトしてある部分を有効にするのが半分くらいでした。

<build_depend>rospy</build_depend>
<run_depend>rospy</run_depend>

<build_depend>message_generation</build_depend>
<run_depend>message_runtime</run_depend>

以上の修正の後、catkin_makeを実行

実行後、rossrvコマンドで作成されたserviceが正しく設定できているか確認できる。

$ rossrv show WordCount

後編へ続く。

[備忘録] rostest試してみた

こんにちは。

以前rostestについて、本で読んでみたものの実際にやってみないとわからんなー、と思ったので本に載ってたサンプルを試してみました。(まんまだとエラーでたので一部修正しましたが。)

参考にしたのは以下。

Programming Robots With ROS
P.366のrostestの説明。

 あとはオフィシャルのwikiを参考にしました。
 http://wiki.ros.org/rostest

ディレクトリ構成とかはよくわからなかったので適当に配置しました。

事前準備

- testディレクトリを作成

CMakeLists.txtを修正した気がしたのですが、修正しなくてよかったみたいです。

テストに使用するトピックはrospy_tutorialのtalkerとlistenerを使用してます。(本で使用している条件そのまま)

launchファイルの作成

launchファイルを以下に書き換えます。
test用ということで、testディレクトリ以下に配置しました。launchでもいいのかもですがなんとなく。

listener_test.test
<launch>
    <node name="talker" pkg="rospy_tutorials" type="talker" />
    <node name="listener" pkg="rospy_tutorials" type="listener" />
    <test test-name="test_talker" pkg="test_sample" type="test_talker.py" />
</launch>


テストコードの作成

サンプルのまんま、test_talker.pyを作成しました。

chatterトピックをsubscribeし、"hello world"があったらsuccessとするテストコード。

テストの実行

以下のコマンドをコマンドラインで実行すると、結果が表示されました。

$ rostest test/lister_test.test

ちゃんと条件を変えたらRESULT:FAILにもなったんで、これを元に今後テストを足していこうと思います。変なとこでつまったんですが便利ですね~。


今回使用したソースコードはこちらに置きました。
https://github.com/zmsn/ROS


test_sampleというディレクトリにまんま置いてあります。

2016年10月27日木曜日

【Book】Programming Robots with ROS Chapter3: topics

こんにちは。

一通り色々試してみたので、もう一回基本をおさらいしようと
Programming Robots With ROS の最初の方から読み直したのでメモ。
Chapter3から。

Published to a Topic


2Hzで/counterにInt32の値をpublishするサンプルが書いてありました。

・topic_publisher.pyのパーミッション変えないと実行できないから注意。

Checking That Everything Works as Expected


サンプルがちゃんと動いてるか確認方法が載ってました。

$ rostopic hz counter

想定している頻度でpublishされているか確認するコマンド。
その他は$ rostopic -h で確認できる。

Subscribing to a Topic


/counterというtopicをsubscribeするサンプルが載ってました。
callbackでmsgを表示するだけ。

Checking That Everything Works as Expected


サンプルをrosrunして、rostopic pubでcounterをpublishして、rostopic info counterでpub/subともに想定通りか確認。

Latched Topics


頻繁にpublishしないtopicの場合、subscribe側がtopicを受け取れないことがある。
(例: mapトピックは基本的に変わらないので、map_serverがdiskから読み込む際に一度だけpublishされる)

Publisherを定義する際にlatchedオプションをTrueにすることで、Subscribe側が自動的に一番最後にPublishされたtopicを読むことができる。

pub = rospy.Publisher('map', nav_msgs/OccupancyGrid, latched=True )

Defining Your Own Message Types


・型に注意。
例えばUInt8がC++だとunsignedだがPythonはsignedで扱われるので、想定と異なる振る舞いをする可能性があるのでC++とPython共存するときは注意

・msgディレクトリのファイルはどの言語を使う場合でも参照される。
独自で定義した場合はPythonを使う場合でもcatkin_makeを実行すること。

独自の型の作り方の例は、実数と虚数を持つComplex.msgをbasicsパッケージに作る
ケースを取り上げてました。
詳細は小倉さん本とかぶるので省略。

Using Your New Message


作ったComplex.msgを使ったサンプルが乗ってました。
使い方はいつものようにimportするだけなので省略。

When Should You Make a New Message Type?


Q:いつ作るか?
A:必要になったときだけ。以上
結構充実してるので使い回せないか確認してから作ろう。

Mixing Publisher and Subscriber


PublisherとSubscriber両方もつ例がここまでなかったのでサンプルを例示していた。

publishは新しいデータが来たときだけ送りたいのでcallbackで実行。

Summary


ROSの通信の基本中の基本topicsについてまとめたよ。
サンプル実際に使うとき使えるから参考にしてねとのこと。

あとはwiki参照とのこと。http://wiki.ros.org/Topics?distro=indigo


以上、3章を読んだメモでした。
サンプルとかは小倉さんの本とほぼ一緒ですが、細かい部分の話が参考になる部分もありました。

次は今までTopicで事足りてたので全然使ったことがないChapter4のServiceを読む予定。

あ、あとrostest使ってみたら意外と情報がググってもわからなかったので手探りでやったのをまとめる予定。

ドラフトとかで

いやいや、そこは即戦力投手指名しとけよみたいなこと思うことないですか?

そういうことを今月2回思いました。

色々と思うようにはいかんもんですねー。
サラリーマンも色々悩むのです。

2016年10月26日水曜日

【備忘録】rostopic pub でマイナスの値を送ろうとしたら失敗したメモ

こんにちは。

やらかした系二連投になるんですが、またやらかしそうなのでメモ。

ロボットを動かすプログラムを書いて、動作確認をする際に、geometry_msgs/Pose2D型のトピック(/hoge)を投げようとして、以下のコマンドをコマンドラインから送ってました。

$ rostopic pub /hoge geometry_msgs/Pose2D 1 1 1


(geometry_msgs/Pose2D型はx, y, theta (すべてfloat))

よし、マイナス方向に動かして戻そう、と思い、以下のコマンドを打ったところ、

$ rostopic pub /hoge geometry_msgs/Pose2D -1 1 1


マイナスとか送れない的なエラーメッセージが出て、あれー?と思って色々とググってみました。

色々とググったり本を読んだ(みんな大好き例の英語の本のP.371が参考になった)結果、どうやら以下のコマンドで送れそうとわかって試してみた。

$ rostopic pub /hoge geometry_msgs/Pose2D "{x: -0.5, y: -1.5, theta:0}"


すると意外なところで以下のエラーがでた。

found unexpected ':'
Please check http://pyyaml.org/wiki/YAMLColonInFlowContext for detail

もう一回例の本をみて、じーっとみてみると。。。ありました、thetaのコロンの後にスペースが入ってませんでした。スペース入れるとか知らんがな。

ということで、以下のコマンドでやりたいことができました。めでたしめでたし。
$ rostopic pub /hoge geometry_msgs/Pose2D "{x: -0.5, y: -1.5, theta: 0}"




【備忘録】callbackでstd_msgs/Emptyの使い方を間違えたメモ

こんにちは。

ROSのcallbackを使う際に、特に受け取ったデータを使わないのでstd_msgs/Emptyを使ったら使い方を間違っていたので今後のためにメモ。

あるノードの開始を/hogestartで通知するのに、特に開始するという情報だけで情報自体は必要なかったので、std_msgs/Emptyを使ってこんな感じで書いてた。(途中省略)

from std_msgs.msg import Empty
...

subscribe ( "/hogestart" Empty, callback)
...

def callback(self):
    rospy.loginfo("start called")
    self._is_start = True


ためしにrosrunをした後、他のターミナルからトピックを送ると、以下のエラーが出て落ちてしまった。

TypeError:  callback() takes exactly 1 argument (2 given)


エラーメッセージから引数が違いそう、ということで、callbackの定義でselfだけでなく引数を以下のように追加したら 無事想定通り動きました。

def callback(self, data):



しょーもないミスでしたけど10分くらい悩んだのでメモがてら残しておきます。。

2016年10月23日日曜日

g_mappingを使用した地図の作り方(後半 最後まで)

こんにちは。

ちょっと放置してしまってた分のメモになります。
Starting a Map Server and Looking at a MapとSummary部分のまとめです。


Starting a Map Server and Looking at a Map

この前の回で取得した YAMLファイルを使用して、ROSで地図を使います。
YAMLファイルは、resolution(map per pixel), 原点の場所、threshold(通行可能か)などの情報を含みます。

roscoreが実行される状態で、以下のコマンドでmap serverをstartします。

$ rosrun map_server map_server map.yaml

このコマンドで、2つのtopicがpublish される。

1. nav_msgs/OccupancyGrid
2. nav_msgs/MapMetaData

[づまメモ]
中身をみたらOccupancyGridはint8[] dataの形なので、各グリッドに対応したOccupancyの値が多分入るんじゃないかな、と思った。
- map_metadataは地図のサイズ(width * height)、resolution(1セルの1辺の長さ)などが書いてある。
- rvizを使うと、実際にYAMLファイルに入っている内容が可視化される。

map_serverの起動は以下のコマンドで行う。

$ roscd mapping/maps
$ rosrun map_server map_server willow.yaml

別のターミナルでrvizを実行する。

$ rosrun rviz rviz

Mapのtypeを追加し、topic名を/mapにし、fixed frameを/mapにすると、地図っぽい図が表示される。

[づまメモ]
この文だとなんのことやらわからんので実際にやってみたほうがよさそう。

今回のサンプルのmapは、PR2ロボット用にレーザーレンジファインダのデータとslam_gmappingを使った地図になります。(以下、作った地図についてのコメントが回てあった。)

1. not axis-aligned
最終的にできたmapがちょっと回転しちゃってるのを修正するのもできるよ、と書いてあった。詳細不明

2. the map is quite messy
データが不十分な部屋とかは自動で入れなかったりする可能性はある。

3. 右下の黒い塗りつぶしについて
gimpとか使ってロボットに入って欲しくない部屋黒く塗りつぶしたりできる、のかな。

Summary

この章ではgmapingの使い方と、rosbagの使い方の説明がありました。

- map作るのは未だに条件によっては結構大変ですよ、と。(安いロボットだったりしょぼいセンサだったり)
- 設定できるパラメータ色々ある、wiki(http://wiki.ros.org/gmapping?distro=indigo)とか論文とか読むとよろしい。
- でもパラメータいじりをやりすぎてもあんま本質的じゃないかも。
- まーとりあえず何回かやってみて感覚をつかみましょう。

みたいなまとめでした。おしまい。

やっとChapter9読み終わった。
次は素直にChapter10のNavigating About the Wolrdに進むのが自然かなぁ。どしよ。
一回色々試しに作ったソースコードやらまとめた方がいいような気もしてきた。

2016年10月19日水曜日

g_mappingを使用した地図の作り方(後半途中)

こんにちは。

前半を読んだ後、後半も読んだんですが放置してたのでそろそろメモ残しときます。

ちなみに違うサンプルでやったらうまくgmappingが使えず、色々とはまるうちにググってみたらROSの英語の掲示板をのぞいてみたら結構充実しててびっくりしました。

世界のどこかで知らない外国の人が自分と同じエラーを踏んだのかー、とほっこりした気持ちになりました。


Building Maps

gmappingパッケージのslam_gmappingを使って地図を作る説明が書いてありました。

・GMappingのアルゴリズムを実装。

・アルゴリズムの詳細は以下の2論文に書いてある。(時間あったら読もう、読むかな。。)
タイトルだけメモっとこう。

-"Improved Techniques for Grid Mapping with Rao-Blackwellized Particle Filters"

-"Improving Grid-based SLAM with Rao-Blackwellized Particle Filters 
      by Adaptive Proposals and Selective Resampling"

今回の解説では、ロボットが動いてる状態で地図を作るのではなく、あえて最初に動いてデータを取得したあとにマップを作る手法の解説がされていました。(大昔に学生の頃似たようなことやった気がする。。)

具体的には
1.ロボット動かしてログをとる
2.gmappingのノード起動
3.rosbagで再生
4.データを保存
の流れでした、以下本で実際にやられてた手順になります。

1.データをとるために、Turtlebotを動かす。


$ roslaunch turtlebot_stage turtlebot_in_stage.launch

このコマンドを実行すると、シミュレータとrvizが立ち上がります。

$ roslaunch turtlebot_teleop keyboard_teleop.launch

キーボードから亀が動かせます、
u i o
j k l
m , . 
あたりで上下左右かな、試してないんで違ったらゴメンナサイ。

$ rosbag record  -O data.bag /scan /tf

data.bagというファイルに/scanと/tfの内容を保存する。

他のオプションは前回まとめた記事参照。

十分ログがとれたかなー、というタイミングでCtrl-Cで終了する。

注意点:ログとり終わったら一旦シミュレーター終了させましょう。
動かしたまんまだと、LaserScanのメッセージが衝突するとのこと。


2.gmappingノードの起動


まずroscoreを再度起動し、以下のコマンドを実行し、gmappingノードを起動する。

$ rosparam set use_sim_time true
$ rosrun gmapping slam_gmapping

1.で保存したファイルで/scanを使ってない場合は、scan:=laser_scan_topicなどで指定できます。


3.保存したファイルを再生

1.で保存したファイルを再生するために、以下のコマンドを実行する。

$ rosbag play --clock data.bag

実行してみたら進捗率みたいなのとか、今どのタイムスタンプあたりを実行してるみたいなログがコンソールにでてました。

4.Mapファイルの保存

2.で実行したgmappingのコンソールをそのままの状態で、別のターミナルで以下のコマンドを実行することでファイルを保存する。

$ rosrun map_server map_saver

実行後、map.pgmとmap.yamlの2ファイルが保存されます。

余談ですが、map_serverとmap_saverが似すぎて打ち間違えて30分時間を無駄にしたアカウントはこちらになります。。。


地図の作り方については基本的には以上になります。

おそらくこの状態ではマップの精度が低いとのことで、以下の2点を試すと制度があがるかもよ、と書いてありました。

・gmappingのパラメータの変更
・ロボットをゆっくり動かす

動かしながら地図を作る場合は、動かしながらgmappingを起動しましょう、とも書いてありました。
著者のお勧めはいったん動かしてbagファイルを作る手法のようです。



。。いかん、後半のつもりがもうちょっとだけ残ってしまった。
続きはまた次回。





2016年10月17日月曜日

PS3のコントローラーを使ってみようかな

こんにちは。

子供が毎日亀はいつ動くの?と聞いてくるので、今週はPS3のコントローラー(家に落ちてた)を使って亀を動かそうと思います。

http://wiki.ros.org/joy/Tutorials/ConfiguringALinuxJoystick
http://wiki.ros.org/turtlebot_teleop

家帰ったらこのへん読んで使い方確認しよう。

【追記 2016.10.19】

家の環境のUbuntuがVirtualBox使ってるせいか、読み込めてるようで読み込めないような不思議な挙動。。小倉さんの本に書いてあったとおりおとなしく別のPCを用意したほうがいい気がしてきた、ちーん。。

g_mappingを使用した地図の作り方(前半)

こんにちは。

ロボットで地図を作るのってどうやるんだろう、とふと思ったら、Programming Robots with ROSのCHAPTER9にそれっぽいことがあったので、読んでみました。


Maps in ROS

・ Mapファイルは画像として保存される。(PNG, JPG, PGMなど)

・ ざっくりいうと、白いとこは行ける、黒いとこは行けない、グレーのとこはunknownと判断

・  YAMLファイルで閾値を設定する。

・ 地図の画像はエディタで修正できるので、例えばロボットに進ませたくない部分を黒く塗ったりできる。

Recording Data with rosbag

rosbagはメッセージを記録/再生するコマンドです。


1. メッセージを保存するとき

$ rosbag record scan tf 


この場合、scan とtfトピックから送られるメッセージをすべて保存する。

オプションを付けないと、YYYY-MM-DD-HH-mm-ss.log形式でログが保存されるので、名前を指定したい場合は -O か -o オプションを使用する。

$ rosbag record -O foo.bag scan tf 
$ rosbag record -o foo scan tf 

前者はfoo.bag、後者はfoo_YYYY-MM-DD-HH-mm-ss.logが保存される。

全てのトピックのログを取りたい場合は、-aを付ける。

$ rosbag record -a

保存したログは、playコマンドを使用して再生可能。 基本的な使い方はこのオプション。

$ rosbag play --clock foo.bag

--clockつけるとログをとった時刻が出力される。

bagファイルの詳細はinfoコマンドで確認可能。

$ rosbag info laser.bag

ログの取得時間の長さ、開始時間、終了時間、サイズなどがわかる。



次回はBuilding Mapsについてまとめる。


2016年10月13日木曜日

subscribeしたデータをpublishしてみた

こんにちは。

ROSで色々試行錯誤でやり始めて早1週間。
今日はあるノードでsubscribeしたデータをpublishするプログラムを書いてみました。

【本日の目標】


具体的にはロボットがセンサのデータをsubscribeして、それを別のノード(ロボット動かすノード)にpublishしたいなーと言うのが今日のゴールです。

【やってみた】

まずは何も考えずにぐわー、っと書いてみたんですが、callbackの中でpublishしていたせいですごい周期でpublishされてうひょっ、となりました。subscribeの頻度ってけっこー頻繁なのね。。


みんなどう書いてるのかなー、とちょっとググってみたら、複数のTopicをSubscribeしてその情報をpublishしてる方がいらっしゃいました。

http://interimadd.com/2016/02/12/ros%E3%81%A7%E8%A4%87%E6%95%B0%E3%81%AEtopic%E3%82%92subscirbe%E3%81%97%E3%81%9F%E6%83%85%E5%A0%B1%E3%82%92%E5%87%A6%E7%90%86%E3%81%97%E3%81%A6publish%E3%81%99%E3%82%8B%E3%83%8E%E3%83%BC%E3%83%89/

ということで、

・callback内ではセンサのデータの更新のみ行う
・別の関数でwhile文とsleep使って周期的に投げる

的な書き方をして、適切な周期でデータを他のノードに送ることができました、めでたしめでたし。

【勉強になったこと】

・callbackで今まで引数は適当にSubscribeで指定した型のものを使うために使用してたんですが、クラスを作る場合&インスタンス変数使う場合は引数selfを追加しとかないと、実行時に怒られた。

こんなかんじで書いたら大丈夫でした。

define callback(self, data):
    self.hoge = data.fuga.fuga.x

Python使ったことないからPythonの勉強しないとですねー。

・rospy.Rateで指定する引数がHzなので、もっと細かくするとき他のやり方あるのかなー、と気になりました。(今後の宿題)

次は週末やらなかったPS3のコントローラーでもつないでみるかなー。

【備忘録】rosrunで引数の渡し方

こんにちは。

ROSで色々作ってて、あ、この変数コマンドラインから指定したいな、と思ったのでやり方を調べたのでメモ。


今回はチュートリアルを読んでみました。

http://wiki.ros.org/ja/rospy_tutorials/Tutorials/Parameters
http://wiki.ros.org/ja/Parameter%20Server


ソースコード内での変数のgetはこんな感じ。


# get a parameter from our private namespace
rospy.get_param('~private_param_name') 

・引数から取得する場合はget_paramを使う。
・'~private_param_name'みたいに"~"がつくのに注意。


コマンドラインで指定するときは、_private_param_nameみたいに設定する変数に"_"をつけて指定。

$ rosrun rospy_tutorials talker _private_param_name:=1.0



こんな感じでparamを指定したらやりたいことができました。

ちなみにちょっと前に読んだrosed意外と使ってます、慣れると便利。

2016年10月12日水曜日

【Book】Programming Robots with ROS 【その5】 rosnode/rostopic/rosmsg/rosservice/rossrv

こんにちは。

やっぱり三連休色々やってるとなかなか難しい、時間作ってやらねば。

最後CHAPTER20の残りを一気にメモ。
よく使いそうなものばっかりだから将来いつか役に立つ、はず。




Introspection: rosnode, rostopic, rosmsg, rosservice and rossrv



システムの内部がどう動いているかをコマンドラインでどう見るか説明するシリーズ。

1. rostopic 


rostopic list
どのトピックが使用可能か確認するためのコマンド。

rostopic list
/chatter
/rosout
/rosout_agg

rostopic info
chatterについて調べる場合は、以下を実行する。

$rostopic info chatter
Type: std_msgs/String
Publisher: XXX
Subscribers: XXX

型とPublisher/Subscribeが確認できる。

さらに、std_msgs/Stringについて調べるときは、rosmsg showを使う。

rosmsg show std_msgs/Strings
string data


subscriberとTopicがわかっている場合、直接Topicをpublishすることが可能。

例:
$ rostopic pub /chatter std_msgs/String "{data: 'Hello world'}"

Ctrl-cで完了

rostopic pub のみだと、1回だけpublishされる。
-r つけると、Hz単位で繰り返し送信可能。

$ rostopic pub -r 10 /chatter std_msgs/String "{data: 'Hello world'}"

subscriber側のコンソールでメッセージが確認できる。

<補足> rostopic param でYAMLもコマンドラインで送れる。

2. rosservice


serviceについてもtopicと同様のことが確認可能。

$ rosservice list
使用可能なserviceの表示

$ rosservice info (サービス名)
rosservice listで表示されたサービス名について、
Node名, URI, Type, 引数を表示。

引数の型の定義を確認する際は、以下のコマンドで確認可能。
例:/add_two_intsについて確認する場合。
$ rossrv show rospy_tutorials/AddTwoInts
int64 a
int64 b
--------
int64 sum
この場合、a,bを指定して、sumが返ることがわかるので、
以下のように実行できる。

$ rosservice call /add_two_ints "{a:40, b:2}"
sum: 42

3. rosnode

nodeについても、rosnodeを使ってコマンドラインで直接情報を確認できる。

$ rosnode list
現状存在するnodeを表示する。

表示されたnodeで気になるnodeについて、以下のコマンドで詳細確認。
$ rosnode info (ノード名)
Publications(publishするもの), Subscription(どのノードのpublishを見るか)
Services(使用するサービス), 他のノードとの接続情報などが表示される。

ノードに対して、状態を確認するのにpingのようなrosnode pingが使用可能。
$ rosnode ping listener
reply from http://XXXX  time=XXXXms
みたいな表示がでてくる。

nodeをkillする場合はrosnode killを使用する。
$ rosnode kill (node名)
killing (node名)
killed

roslaunchコンソールで、killしたノードがshut downしたか確認できる。


Summary


ROSで使う基本的なツールについて紹介されている章でした。

roscore: 一番最初にrunするよ
rosparam: parameterを見たり設定したりする
roscd: cdするときパスとか指定しなくて楽
rosed: 好きなエディタでソースコードが開かれるよ、パスの指定もしなくていい
rosrun: 1つのNodeを実行
roslaunch: 複数のNodeを実行
rostest: 複数のNodeのテストを実行。roslaunchに<test>を追記
rosnode: Nodeに関する操作が色々できる
rostopic: Topicに関する操作が色々できる
rosmsg: メッセージの型を確認する
rosservice: サービスに対して色々できる。
rossrv: 指定する引数と返り値を確認する

2016年10月11日火曜日

【Book】Programming Robots with ROS CHAPTER20 【その4】rostest

こんばんは。

子供の運動会で気づいたら寝落ち。。
おっさんは体力が落ちるんだなー、ということを実感しました。。

前回の続き、そろそろchapter20を読み終わりたい。


Testing a Many-Node System: rostest

・ROSに限らずテストするときは標準的なフレームワーク使いましょう(noseやGoogle Testなどなど)
・これらは単独でのテストには素晴らしく使えるけど、ROS system全体向けにはちょっと厳しいので、rostest を使いましょう。

【使い方】
・roslaunchの拡張で、テストプログラムに関する情報を<test>タグを使って追加しましょう。
例: <test test-name="test_talker" pkg="basics" type="test_talker.py" / >

・roslaunchとの違いは、test nodeを追加でlaunchして、残りのノードが正しく動くか試して、結果を出力する。

【補足】
<test>タグを複数launchファイル内に記載した場合、rostestは順番にそのtestを実行する。その際に、毎回環境をクリーンしてから次のテストを実行するとのこと。

【サンプル】
・テスト用にunittest, rostest, timeをimport。
・"chatter"にSubscribeし、10秒以内に所定の文字列を受信したらテスト成功。
・callbackで文字列受信("hello world")したら内部のフラグをtrueにする。
・テストの実行はrostest.rosrun()で行う。

簡単なサンプルが書いてあって、どう書けばいいか参考になりました。

続きのIntrospection: rosnode, rostopic, rosmsg, rosservice and rossrv について途中までメモ書いてみたけど、意外とまとめるのがめんどくさそうなのでまた後日。

全然関係ないですが、幼稚園児が左の鼻から鼻水、右の鼻から鼻血を同時に出していて(器用!)、まだまだ自分も精進が足りないな、と思いました。


2016年10月9日日曜日

【Book】Programming Robots with ROS CHAPTER20【その3】rosrun/roslaunch

続いてrosrunを読んだメモ。

Starting a Node: rosrun

実行したいnodeのパスも忘れがち〜。
rosrunを使えば、package名とnode名だけ指定すればおk。

例: $ rosrun my_package my_node

rosrunで実行したnodeはCtrl−Cでkillできます。

Starting Many Nodes: roslaunch

rosrunでnodeを開始するのはテストとかデバッグの時はいいけど、正直しんどい。
ROSシステムは基本多数のノードを使うから個別にやるのほんとしんどいので、ファイルに書いてまとめてしまいましょう。この時に使うコマンドがroslaunchになります。

・xmlに書く。指定するのは以下。
name: ノードの名前
pkg: パッケージ名
type: executable file の名前

・fileの拡張子はXXX.launch
・実行停止はCtrl-Cですべてのノードが終了。
・すでroscoreが実行されていたらそれを使う、実行されてなかったら自動でroscoreを実行し、終了時にkillする。
・実行時にコンソールには何もでないからびっくりするよね。output="screen"て追加すると見えるっぽい。
・<remap>タグを使うと、通信するtopicをdefaultから変えることができる。
・launchファイル内で他のlaunchファイルをinclude可能。

以上、rosrunとroslaunchの部分のメモ終わり。
rosrunはパス覚えなくても楽だね、roslaunchは複数のノードまとめて開始できるよ、あとこうやったら便利に使えるよ、てのが書いてありました。あ、launchファイルはlaunchディレクトリに置いて使うっぽいです、たしか。


次回はrostestについて。
ROSのテストって全然まだわかってないから読むのが楽しみ。


2016年10月8日土曜日

【Book】Programming Robots with ROS CHAPTER20【その2】roscd

今日はroscdの部分を読んだまとめ。

Navigating the Filesystem: roscd

作ったパッケージのパス、忘れがち〜♪。(ROSあるある〜by RG)
早く目的のディレクトリに移動するのにroscd使うと直接飛べて便利。

例:$ roscd my_package

roscd使う前にはsetupファイルの実行する必要あり。

例:$ source /opt/ros/indigo/setup.bash

関連するコマンドとして、rosedコマンドを使うと、該当のディレクトリに移動しなくても指定したパッケージのファイルが自分の好きなエディタ(環境変数 EDITORで指定)で編集できるよ。

例:$ rosed my_package my_file.cpp


以上、roscdの部分のまとめ、終わり。

うーむ、昨日まで書いてたのよりすっきりしててわかりやすい気がしてきた。
だらだら書かずにこの粒度でメモを残していこうかしら。

今朝の会話

奥さんに聞いてみた。

『ルンバって改造したらだめか』

『うん!』

な?を言う前に食いぎみで言われました。。

作戦を考えねば、うーむ。

【Book】Programming Robots with ROS CHAPTER 20 読んだ【その1】

こんにちは。

前回CHAPTER23から始めたから次は22かな、と思ってたのですが、気分屋なのでCHAPTER20(Tools)読み始めました。

1日1チャプターペースで読んでいけば今月末には一通り読めてる、はず。
頑張れ未来の俺。

=============================================================

CHAPTER20 Tools

効率的なソフトウェア開発には良い開発ツールが必要です。
 エディタ、バージョン管理システム、テストフレームワーク。

この章ではいつ、どうやってROSのツールを使うか説明しています。

⚪️The Master and Friends: roscore
roscoreの説明。以前の章で触れられているが、実際に何をしているかをこの章では 取り上げている。

roscoreを実行すると、3つのツールが開始される。

1. master: name serviceをhandle
2. parameter server: key/value parameterを保持する
3. rosout node:すべてのノードからデバッグメッセージを集める

ROS nodeは開始時に自分自身を登録するためにmasterにアクセスするので、masterがない状態でnodeを開始しようとすると、以下のような警告がでます。
 Unable to register with master node (省略、やってみてね。)

登録時に各ノードは自身のnetwork addressを提供する(後で各々通信するために)
マスターはそのアドレスをテーブルで管理する。

登録時に各ノードはsubscription, advertisements, servicesについても登録する。
例えばrospy.Publisherを使うときには、自分のノードはpublisherだとrospy libraryがmasterに登録する。publisher listを元に、subscribe側のノードは自分が読みたいtopicがないか探して、その後直接pub->subへデータが送られる(masterを介在せずに。)

name lookupで重要な役割を果たすmasterは、例えばkillされてしまった場合、リカバリー不能となることが多い。すでに動いているノードはそのままでも、新しいnodeは通信を行えないし、新たにconectionはできない。masterが死んだら再起動しましょうね。

ただし、ロボットが無線の届かないとこに一瞬行った、とかならば再度電波が届くようになったら再開できるようにしとくべし。幸運なことにmasterはロバストでツールもよくテストされてるよ、とのこと。

nodeがcrashした場合、普通は大きな問題ではないが、もはやだめ、ってときにはrosnode cleanup をやればまっさらになる。

⚪️Parameters: rosparam
parameter serverについての説明。
key/valueの辞書の管理。

key: string
value: どの型もとりうる。

どのnodeもparameter serverからread/write可。

注意:Parameterはconfiguration用、communication用ではない。
高頻度のやりとりにparameter使うとパフォーマンスが出なくてがっくりしくるよ。
そういう場合はtopicsを使いましょうね。

普通はcodeからparameterにアクセスされるが、(rospy.get_param()/rospy.set_param()) コマンドラインからもset/getできます。

やり方の例はこんな感じ。

$ rosparam list 
パラメータが表示される。
$ rosparam set my_param 4.2
$ rosparam get my_param
4.2
みたいな使い方。

Parameter valueはYAMLでも設定できます。

============================================================
長くなったので続きのroscdは今度書きます。

【感想・まとめ】
roscore, ros_param (parameter server)について書いてある部分を読みました。

・roscoreが死んじゃったらその後は新しいnode追加とか、新しい通信とかできないから
再起動しましょう。
・nodeが死んでも全体としては特に問題ないけど、どーしようもないとき(?)rosnode cleanupするといいらしい。
・parameter serverはconfiguration用、high-volume, high-rateのnode間の通信には使わないほうがいいよ、topic使おうね。

みたいなことが書いてあった気がします。

前回はほぼ要約で今回はほぼ翻訳のような統一性のなさ、次回どうしようかしら。。
まー後で読んで自分でわかればいっか。

英語読むスピードが遅くなってるなー、と思って読み始めたのですが、一旦日本語の本で内容を読んでから読んでみたらそんなにスピードが気にならなくなってきました。最近まで英語もロボットもご無沙汰だったので完全にリハビリ生活でございます。。

おやすみなさい〜、次回はNavigating the Filesystem: roscdから。








2016年10月7日金曜日

【Book】Programming Robots with ROS CHAPTER 23 読んだ

前のエントリーで書いたProgramming  Robots With ROSのChapter 23 を読んでみた。
一番最後の章から再開するあたりが自分らしいというか残念というか。




だーいたい内容をメモったので書いておきます、英語最近使ってないので嘘っぱちだったらごめんなさい。日本語版でないのかな。


CHAPTER 23 Using C++ in ROS

○概要

・この本でPythonを使った理由
1.初心者でもとっつきやすい
2.core packageが充実しているので、泥臭い部分無視で上の方に集中して開発可能
3.ROSがPythonを強力にサポートしてる
4.(著者が)元々すべてのサンプルを1つの言語で書こうと思ってた

・でもPython以外の言語で書きたいことがあるかもしれませんね。
 例えば(滅多にないかもですが)実行速度の問題とか。

・C++での書き方についてこの章では説明します。
 callback使ったり、topic使う部分はPythonと基本共通です。
 文法とかデータ構造とか違います

・ROSの2大メジャーな言語はC++とPythonです。
・この章はC++について書いてあるけど、他の言語にも適応できる内容です。

○いつC(もしくはその他の言語を)使うべきか?(When Should You Use C(or Some Other Language)?)
・答え:使って楽になるとき使おう

・ROSは同じシステム内で、異なる言語で書かれたノードが混在する場合でも、簡単に開発できます。
C++が得意ならC++使えばいいし、もしC++の資産があればC++使えばいい。


・もし複雑な計算をするときに、C++で書いて高速化、と考える場合1点注意してください。
Pythonのライブラリ(scipyとか)も結構最適化されてるから、わざわざC++で書く必要があるかをちゃんと考えてから選びましょう


○catkinでC++をビルドする
- Pythonとの最大の違いはコンパイルするかしないか
- C++の場合修正するためにビルドする必要があるよ
- (作者たちの意見だけど)コンパイルし直すのがめんどいからPythonがよく使われるのでは?
- 規模が大きくなった場合、コンパイルに数分かかるようになる。開発効率が落ちるかも

以下の3ファイルをC++使うとき修正するよ。

1.package.xml
手動で修正 or catkin_create_pkgで修正できます。
例:user@hostname$ catkin_create_pkg <package name> roscpp


2.CMakeLists.txt
  build対象の.cppファイルを追記する。
  例:minimalというexecutableをminimal.cppから作る場合
 add_executable(minimal
   src/minimal.cpp
  )
 ライブラリについてはcatkinがよろしくやってくれる?
 
 
3.catkin_make
 ビルドするときは、catkin workspaceのrootでcatkin_makeを実行する。
 ビルドが成功すると、minimalの場合、以下の場所にminimalが作成される。
 catkin_workspace/devel/lib/<package name>/minimal

 
○Translating from Python to C++(and Back Again)
・A Simple Node
・Topics
・Services
詳細は省略。(サンプルはPythonで一回書いたことあればわかりやすい感じです)
- #include <ros/ros.h>はincludeしましょう
-初期化:ros::init(argc, argv, "minimal")
-ros::ok()でCtrl-Cされた条件を見てる。
 
・Summary
 一回書き換えやっとけば簡単に書き換えれるようになります。
 結論:好きな言語使えばいいよ。

【Book】ROSの本読み比べてみた

こんにちは。


急にロボットが動かしてみたい欲が高まったので、今週はROSの勉強をしてみました。

とりあえず3冊ほど買ったり借りたりした本があったので、読んだ結果をまとめておきます。
(1冊だけ英語がつらくて全然読んでないんですが、なんとなくの感想だけ。)


1.ROSではじめるロボットプログラミング―フリーのロボット用「フレームワーク」




この本は最初から最後まで一通り読んでみました。


著者の小倉さんは趣味でも仕事でもロボットをずっとやっている人らしく、この本を読んだ後にこういうことやってみよう、とググってみたらだいたい小倉さんがすでにやってるブログの記事が引っかかりました、お釈迦様の掌の上感がすごい。

サンプルはPythonで書いてあり、Topic、Subscribe、Publishの基本的な使い方や、同期/非同期の実装方法、C++の書き方紹介など、実際に色々書いてみることでざっくりと短時間で理解できました。

僕みたいにROSの知識がない状態で最初に読む本としてはお勧めです。


2.ROSプログラミング




1の小倉さん本を読んだ後に読んでみました。(基本の部分はがっつり読んで、応用のとこは流し読み)

小倉さんの本より細かい内容に言及されています。サンプルはC++で書かれてます。


小倉さんの本も最後のほうにC++のサンプルが書いてあったのですが、さらに調べてみたい場合は読んでみるといいかもです。Wikiを読んどけばOK、な気もします。



3.Programming Robots With ROS



実は最初にこの本を読み始めたのですが(知り合いにもらった)、英語を読むスピードが遅すぎるため、途中で読むのをやめて小倉さんの本を読みました。


ただ小倉さんの本を読んだ後にぱらぱらと読んでみたらすらすら内容が入ってきた(気がする)ので、これから続きを読んでみます。まだ30ページくらいしか読んでませんが、最初のほうからわりと細かい内容(tfとか)まで言及されてた、気がする。(ちょっと前に読んだのでうろ覚え。)

サンプルはPythonで書かれてました。小倉さんの本と同じくChapter23 にC++での書き方が書いてありました。ちょっと読んだのであとでまとめよう。


以上、とりあえず今週3冊パラパラと読んで、なんとなくROSについてわかり始めてきた気がします。


感想としては大昔にロボットを作ったことがあるのですが、XX年たつと色々と環境が変わってるな~、と大変興味深かったです。昔は自分で作る部分が多く、学生の頃に一人でやるにはヒーヒー言いながらやっていた記憶があるのですが、一日でGazebo使うところまで言ってツールもスゲー恵まれてるな、いいなー、とおじさんは今の学生さんがうらやましくなりました。


家のルンバを奥さんにばれないように改造するのをゴールとして頑張ろうと思います。
3の本の感想追記と書いてるソースコードは別途どっかに置こう。

初投稿

こんにちは。

最近読んでる本とかどっかにまとめておこうとふと思いまして、自分のメモ用にまとめていくことにしました。

いつまで続くかわかりませんがよろしくお願いします。