ROSを使用したCRANE+の動かし方 その11(完結)

こんにちは!長谷川です。
前回はCRANE+の状態をモデルに反映させる方法について説明しましたが、今回は、CRANE+の状態をrviz上でモニタリングしつつ、CRANE+を自動で動かす方法について説明したいと思います。

使用するプログラム

実は、今回やろうとしていることは、すでに勉強したことの組み合わせで実現できます。
CRANE+を自動で動かすプログラムは第6回目の記事で作成済みですし、CRANE+の状態をrvizに反映させるプログラムも第10回目の記事で作成済みです。それぞれのプログラムで立ち上げられるノード名、関係するトピックは異なっているので、これら2つのプログラムを同時に起動できれば、目的を達成できることになります。

launchファイルの利便性

今まで勉強してきたことを組み合わせると、今回は以下のような手続きをすればいいことになります。

1: CRANE+とPCを接続
2: 「sudo chmod 6666 /dev/ttyUSB0」と端末に入力
3: 「roslaunch my_dynamixel_tutorial controller_manager.launch」と入力
4: 新しい端末を開き、「roslaunch roslaunch my_dynamixel_tutorial start_tilt_controller.launch」と入力
5: crane_urdf/srcに移動し、「roslaunch crane_urdf display.launch model:=crane.urdf」と入力
6: 新しい端末を開き、「rosrun crane_urdf reflect_crane_in_rviz」と入力
7: 新しい端末を開き、「rosrun turtlebot_arm turtlebot_arm」と入力

・・・面倒ですね。この面倒な作業を軽減するため、新たなlaunchファイルを作ることにします。これにより、少なくとも5〜7までの手順をコマンド1回で行うことができるようになります。プログラムの方に多少手を加えれば、3〜7までの作業をコマンド1回でできるようになります。

ROSのlaunchファイルについて

前回、display.launchというlaunchファイルを作りましたが、この時にはlaunchファイルについて詳しく説明しませんでした。今回は、display.launchについても詳しく説明しつつ、新しいlaunchファイルを作っていこうと思います。
launchファイルとは、様々なプログラムを組み合わせ、複数のノードを同時に立ち上げることができるファイルです。「roslaunch」というコマンドは、このlaunchファイルを起動するためのものだった、というわけです。このファイルに書いておけば、立ち上げたい全てのノードを1回のコマンドで立ち上げることができます。いちいち「rosrun」する必要がなくなるのです。しかもこのlaunchファイル、内部で他のlaunchファイルも実行することができます。また、それぞれのプログラムに対するパラメータも、ファイル内で決めておくことができるのです。このような機能により、操作がとても楽になります。それだけでなく、プログラムを別個の処理ごとに分けることが容易になるので、モジュール化と再利用性の向上を図ることができるのです。今回の場合では、CRANE+を動かすプログラムとCRANE+の状態をrvizに反映させるプログラムは独立に動いているので、CRANE+の動かし方を変えたいときは、CRANE+を動かすプログラムのみ変更すればいいという事になります。

新しいlaunchファイルの作成

例のごとく解説は後回しにして、まずはlaunchファイルを作ってしまいましょう。
端末に、
[php]
$ roscd crane_urdf/src
$ vi auto_crane_rviz.launch
[/php]
と入力します。以下を貼り付けます。
[xml]
<launch>
<param name="robot_description" textfile="$(find crane_urdf)/src/crane.urdf" />
<param name="use_gui" value="False"/>
<rosparam param="source_list">["joint_states_source"]</rosparam>

<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
<node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher" />
<node name="rviz" pkg="rviz" type="rviz" args="-d $(find urdf_tutorial)/urdf.rviz" required="true" />
<node name="reflect_crane_in_rviz" pkg="crane_urdf" type="reflect_crane_in_rviz" />
<node name="turtlebot_arm" pkg="turtlebot_arm" type="turtlebot_arm" />
</launch>
[/xml]
貼り付けたら、保存してviを終了してください。これで、新しいlaunchファイルが完成です。

実行

早速、新しいlaunchファイルを実行してみましょう。
第5回目の記事にしたがって、CRANE+とPCを接続し、「roslaunch my_dynamixel_tutorial start_tilt_controller.launch」まで入力してください。これで、1〜4までの手続きが終わりました。その後、端末に、
[php]roslaunch crane_urdf auto_crane_rviz.launch[/php]
と入力します。これで、CRANE+も動き始め、rvizも起動すると思います。天板上で動くので、天板にPC等を置くのは危険です。

launchファイルの解説

auto_crane_rviz.launchを見ながら、launchファイルの書き方について学びましょう。
[xml firstline=”1″]<launch>[/xml]
[xml firstline=”11″]</launch>[/xml]
この2つで囲まれた部分が、launchファイルとして認識されます。
[xml firstline=”2″]<param name="robot_description" textfile="$(find crane_urdf)/src/crane.urdf" />[/xml]
ここでは、robot_descriptionというパラメータに、crane_urdfパッケージのsrcディレクトリ内にあるcrane.urdfファイルを設定します。パラメータというのは、変数のことです。パラメータサーバというパラメータを共有できる仕組みがあって、ノードがそこで定義されたパラメータを読み込んで動作に反映させています。このパラメータをノードの外から変更することで、ノードの設定を変えることができます。
こちらこちらを読むと、robot_descriptionというのは、joint_state_publisherとrobot_state_publisherにおいて、ロボットのURDFデータを格納するパラメータのようです。ここに、第8回目の記事で作成したcrane.urdfを設定することで、モデルを読み込ませます。
[xml firstline=”3″]<param name="use_gui" value="False"/>[/xml]
先ほど紹介したページを読むと、use_guiというのは、joint_state_publisherにおいて、各関節の値をスライドバーで変更できるウィンドウを出すかどうかを決めるパラメータのようです。ここにFalseという値を設定することで、ウィンドウを出さない設定にします。なお、前の行ではパラメータ名を指定した後、「textfile=」と書いていましたが、これはファイルの中身をパラメータに設定するためのコマンドです。この行では、値を直接設定するため、「value=」と書いています。
[xml firstline=”4″]<rosparam param="source_list">["joint_states_source"]</rosparam>[/xml]
rosparamタグは、先ほど使ったparamタグに似ています。paramは主にひとつずつパラメータを設定しますが、rosparamはyamlファイルという、パラメータをまとめてあるファイルを読み込んで、複数のパラメータを一度に設定することが可能です。この行では、yamlファイルを読み込んでいるわけではなく、source_listという一つのパラメータしか設定していません。ですが、source_listには文字列のリスト型を設定しなくてはならず、paramタグではリスト型を設定できるのかよくわからないため、rosparamタグを使用しました。なおリスト型というのは、例えば[3, 4]のように値を並べたものです。source_listパラメータの働きについては、前回説明しましたので、割愛します。
[xml firstline=”6″]<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />[/xml]
ここではノードを立ち上げています。「name=”joint_state_publisher”」で、立ち上げるノード名をjoint_state_publisherとし、「pkg=”joint_state_publisher”」でノードの動作が書かれた実行ファイルはjoint_state_publisherパッケージにあると宣言します。次に、「type=”joint_state_publisher”」で、joint_state_publisherが実行するファイルであると宣言します。以上の項目が、ノードを立ち上げるために必要な最低限の宣言です。
[xml firstline=”8″]<node name="rviz" pkg="rviz" type="rviz" args="-d $(find urdf_tutorial)/urdf.rviz" required="true" />[/xml]
ここもノードを立ち上げる文ですが、いくつかオプションが付け加えられています。「args」というのは、ノードに渡す引数です。端末上でプログラムを起動するとき、コマンドライン上で引数を渡すことができますが、あれと同じようなものですね。「required」というのは、ノードが停止した時にroslaunchを停止させるかどうかを設定できます。ここに「true」を設定しているので、rvizノードが停止すると、roslaunch全体が停止します。

これで、auto_crane_rviz.launchで何が行われていたかは大体説明できたと思います。launchファイルについてもっと詳しく勉強したい方は、こちらをご覧ください。で、読んでいくと、includeタグなるものがあります。これは、launchファイル内で他のlaunchファイルを実行するためのタグです。これを使うと、「roslaunch my_dynamixel_tutorial controller_manager.launch」と「roslaunch roslaunch my_dynamixel_tutorial start_tilt_controller.launch」もauto_crane_rviz.launch内で実行することができます。この場合、以下のように書けばOKです。
[xml]
<launch>
<param name="robot_description" textfile="$(find crane_urdf)/src/crane.urdf" />
<param name="use_gui" value="False"/>
<rosparam param="source_list">["joint_states_source"]</rosparam>

<include file="$(find my_dynamixel_tutorial)/controller_manager.launch" />
<include file="$(find my_dynamixel_tutorial)/start_tilt_controller.launch" />
<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
<node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher" />
<node name="rviz" pkg="rviz" type="rviz" args="-d $(find urdf_tutorial)/urdf.rviz" required="true" />
<node name="reflect_crane_in_rviz" pkg="crane_urdf" type="reflect_crane_in_rviz" />
<node name="turtlebot_arm" pkg="turtlebot_arm" type="turtlebot_arm" />
</launch>
[/xml]
ところが、これだと起動当初にCRANE+が暴走します。なぜかというと、controller_manager.launchやstart_tilt_controller.launchの処理が終わっていない状態、つまり初期設定ができていない状態で他のプログラムが走りだすからです。これを解決するためには、reflect_crane_in_rviz.cppやturtlebot_arm.cppの最初にwaitを入れてやればいいです。または、ROSだけに頼らず、シェルスクリプトを使うという手もありますが、今回は割愛したいと思います。

以上、CRANE+の状態をrviz上でモニタリングしつつ、CRANE+を自動で動かす方法について説明しました。
とりあえず、CRANE+とROSの組み合わせでできることの基本は解説できたと思いますので、今回でCRANE+の連載は終わりにしたいと思います。ここまでお読み下さり、ありがとうございました。

ロボカップジャパンオープン2015 @ホームリーグ報告

出村 賢聖です!ロボカップジャパンオープン2015@ホームSPLリーグに参加してきました!
robocupathome
RoboCup@homeリーグロボット/選手集合写真

ロボカップ@ホームSPLリーグ

splrobots
RoboCup@home SPLリーグロボット集合写真

SPLリーグでは出村の1名チーム D.K.T. IcARusは6チーム中5位になることができました!後日賞状が送られてきます!Turtlebotを貸していただき、東京から福井の大会会場まで車に乗せていただいたRT Corporation、本当にありがとうございました!

RTでの準備

ロボカップ@ホームSPLリーグに向けてタスクのための開発を始めたのは大会1週間前です。それまで色々なことがあって手が回りませんでした。
今回はfollowmeタスクにしぼって開発を進めました。
followmeはロボットが家環境で特定の人を追跡する競技です。

TurtlebotのROSの人間追跡パッケージの問題点

人の追跡にturtlebot_followerという既存のturtlebot用人間追跡ROSパッケージを使用していたのですが、間違えて机の方に向かったり、壁に向かったりなど誤認識が多いです。
turtlebot_follower
誤認識の理由はturtlebot_followerの人間追跡アルゴリズムにありました。
turtlebot_followerのアルゴリズムは、kinectの深さカメラが捉えられる範囲内で最短距離の物体を追跡対象として認識し、追跡する、というものです。
followme競技中、追跡対象はこの条件を満たさないときがあります。
追跡対象である人が机を横切ったり、他の歩行者を通り過ぎると、追跡対象でない物体が追跡対象として認識されてしまいます。
そこで追跡アルゴリズムを改善する必要がありました。。

人間追跡の精度を向上させる方法

人の色情報を活用すれば、認識精度が向上した人間追跡をすることができるのではないかと思いました。
例えば、追跡される人の靴の色は赤、ズボンの色はピンク等、髪の毛は黒、のような色情報です。
そこで今回はCamShiftというアルゴリズムを人間追跡に使用しました。(CamShiftアルゴリズムの説明は後ほど行います)

人間追跡ソフトウエアの開発概要と苦労した点

kinectの画像情報 → CamShiftで追跡者の位置を特定→追跡者位置情報をもとにTurtlebotを制御する
開発するソフトウエアにはこのようなフローが必要になります。
今回はROSというロボットミドルウエア上で、画像情報を取得し、Turtlebotの移動制御を行います。
ここで問題になったのが、ROSの画像型(クラス)→Opencv画像型(クラス)変換や、Opencvの人間追跡コードをroscpp(イベント駆動)で記述するとsegmentation faultを起こすことです。(C++で開発しています)
そこでgdbでデバッグを行ったのですが、ROS Nodeではgdbでソースコードを読みながらステップ実行ができません。バックトレースを見ても参考になるサブルーチン名が出てくることはなくgdbではあまり有用なデバッグができませんでした。printfデバッグを使用すると、OpenCV用のGUIウィンドウの初期化に問題があることが判明しました。問題の箇所は判明したのですが、このときは残念ながら人間追跡のソフトウエアの開発が完了しませんでした。

会場での準備/調整

camshift_node
人間追跡ソフトウエアのデバッグを続けました。
OpenCVのGUIウィンドウの初期化をROS Topicのコールバック関数内に記述せずに、main関数内で初期化を行うとsegmentation faultの問題が解決しました。
追跡者の方位を認識した画像のピクセル位置とkinectのFOV(43°)から計算し、追跡者の距離をkinectで計測、そしてTurtlebotに比例航法とPD距離制御を使って人間追跡ができるようになりました。
これで人間追跡が可能になりました。

Basic Functionalities競技

SPL
Basic Functionalitiesでは惜しくも無得点になってしまいました。 ロボットが家で障害物回避をしながら部屋の好きな場所に移動するAvoid Thatは得点することができるはずでした。
原因は、調整中Avoid Thatのための環境地図を生成していたときスタート地点に人がいたためです。人を障害物として認識してしまいスタート地点から動くことはありませんでした。
Avoid That(家で障害物回避をしながら部屋の好きな場所に移動する)に使用したプログラム

Restaurant競技

IMG_20150503_094419
Restaurantでは惜しくも無得点になってしまいました。Restaurantでははじめに人間追跡をしながら地図生成をするのですが、ロボットが移動時に何回も転倒しそうになりました。これは重心が高い位置にあったのが原因です。そのためロボットアームを外し、下に2kgのおもりをつけることで重心を低くし転倒を防止しました。

Follow Me


Follow Meでは181点得点することができました!
僕がRoboCup@home SPL leagueで使用したfollowmeのソースコード(ROS Node)を公開していますのでぜひ活用してください!
ソースコード
人間追跡にはCAMShift(Continuous Adaptive Mean Shift)というアルゴリズムを使用しています。
CAMShiftはヒストグラムマッチング(色情報)を使った画像追跡のアルゴリズムです。
Mean Shiftアルゴリズムの数学的説明(CAMShiftはMean Shiftの拡張版)

出村のfollowme ROS Node を使用するには

※Turtlebotを動かすROSパッケージとkinectのドライバを入れる必要があります。 ROS Indigo対応
ビルド

[c]$ cd ~/catkin_ws/src[/c]
[c]$ git clone https://github.com/kendemu/followme[/c]
[c]$ rosdep install followme[/c]
[c]$ catkin_make[/c]
実行
[c]$roslaunch turtlebot_bringup minimal.launch[/c]
[c]$roslaunch turtlebot_bringup 3dsensor.launch[/c]
[c]$rosrun followme followme_node[/c]
CAMShiftと書いてあるウィンドウの方を選択し、画像ウィンドウの中の追跡対象をマウスで範囲選択してください。
このプログラムは追跡対象を認識し、その角度を算出します!
[c]$rosrun followme distance_node[/c]
このプログラムは追跡対象が位置する角度情報を元に追跡対象への距離を計測します!
[c]$rosrun followme trackme_node[/c]
このプログラムは追跡対象の角度情報と距離情報を元に追跡対象を追跡します!

Technical Challenge


Technical ChallengeではTurtlebotが屋外の走行も可能であること、ROSのセキュリティ面の問題とドローンの拡張現実ゲームであるDrone Space Defenseのことをお話しました。
Turtlebotの屋外の走行の速度検証(100P参照)
ROSのセキュリティ面の問題

かわいい生活支援ロボット達

IMG_20150503_114918
左はトヨタの生活支援/テレイグジスタンスロボット HSR、右はdemura.netチームのKenseiko chan 2 mobileです!

ロボカップジャパンオープンでの反省とロボカップ@ホームリーグ世界大会に向けて


demura.netチームの一員として7月のロボカップ世界大会に参加します!
ロボカップ世界大会では、ロバストな画像追跡を実現する予定です!

今回のロボカップジャパンオープンでの反省点は画像追跡/物体認識が正確ではないことです。
色情報だけでの追跡(CAMShift)では追跡対象の識別が正確ではないことがわかりました。追跡対象のズボンの色が青のとき、青色のカーテンの方を追跡してしまうことがありました。followmeの競技中は追跡対象の靴の色がユニークな色で、その靴の色情報を元に追跡したので正確に追跡対象を追跡してくれました。
色情報以外に追跡対象の位置情報、深さカメラの情報を利用して正確な画像追跡をする必要があることがわかりました。
世界大会までにこの問題を解決します!
これからもよろしくお願いします!

ROSを使用したCRANE+の動かし方 その10

こんにちは!長谷川です。
この連載も、ついに10回目に突入しました。ここまで見てくださった皆様、本当にありがとうございます!
前回は、前々回作ったモデルと実物のCRANE+の連動のさせ方について説明しましたが、今回は、CRANE+の状態をモデルに反映させる方法について説明したいと思います。

依存関係の追加

今回書くプログラムを、前々回に作ったcrane_urdfパッケージ上で動かすためには、crane_urdfパッケージの依存パッケージが不足していると思います。そこで、依存関係を追加しましょう。端末を開いて、
[php]
$ roscd crane_urdf
$ vi CMakeLists.txt
[/php]
と入力します。前回はこの末尾に3文貼り付けましたが、今回は違う場所を編集します。
[php firstline=”7″]
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
sensor_msgs
std_msgs
)
[/php]
などと書かれているところがあると思います。roscpp,rospy,sensor_msgs,std_msgsの順番は、パッケージを作った際に記述した順番などにもよると思うので、あまり気にしないでください。この依存パッケージ群の中に、dynamixel_msgsを追加します。具体的には、以下のように修正します。
[php firstline=”7″]
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
sensor_msgs
dynamixel_msgs
std_msgs
)
[/php]
ここを書き直し終わったら、保存してviを終了してください。
次に、[php]vi package.xml[/php]と入力して、package.xmlを開きましょう。
[xml firstline=”42″]
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<build_depend>rospy</build_depend>
<build_depend>sensor_msgs</build_depend>
<build_depend>std_msgs</build_depend>
<run_depend>roscpp</run_depend>
<run_depend>rospy</run_depend>
<run_depend>sensor_msgs</run_depend>
<run_depend>std_msgs</run_depend>
[/xml]
などと書かれているところがあると思います。他の依存パッケージの例にならって、dynamixel_msgsも追加します。具体的には、以下のように修正します。
[xml firstline=”42″]
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<build_depend>rospy</build_depend>
<build_depend>sensor_msgs</build_depend>
<build_depend>dynamixel_msgs</build_depend>
<build_depend>std_msgs</build_depend>
<run_depend>roscpp</run_depend>
<run_depend>rospy</run_depend>
<run_depend>sensor_msgs</run_depend>
<run_depend>dynamixel_msgs</run_depend>
<run_depend>std_msgs</run_depend>
[/xml]
修正し終わったら、保存してviを終了してください。これで、依存関係の追加は完了しました。

新しいdisplay.launchの作成

前回、
[php]roslaunch urdf_tutorial display.launch model:=crane.urdf gui:=True[/php]
なる命令を実行していました。この際、urdf_tutorialというパッケージ内のdisplay.launchを立ち上げていましたが、このdisplay.launchのままだと、今回実行したいプログラムが実行できません。そこで、新たなdisplay.launchをcrane_urdf内に作ることにしました。端末に、
[php]
$ roscd crane_urdf/src
$ vi display.launch
[/php]
と入力します。以下を貼り付けます。
[xml]
<launch>
<arg name="model" />
<arg name="gui" default="False" />
<param name="robot_description" textfile="$(arg model)" />
<param name="use_gui" value="$(arg gui)"/>
<rosparam param="source_list">["joint_states_source"]</rosparam>
<node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" />
<node name="robot_state_publisher" pkg="robot_state_publisher" type="state_publisher" />
<node name="rviz" pkg="rviz" type="rviz" args="-d $(find urdf_tutorial)/urdf.rviz" required="true" />
</launch>
[/xml]
貼り付けたら、保存してviを終了してください。これで、新しいdisplay.launchが完成しました。完成しましたが、何やってるのかさっぱりな方も多いと思います。基本的には、urdf_tutorialパッケージのdisplay.launchの真似ですが、
[xml firstline=”6″] <rosparam param="source_list">["joint_states_source"]</rosparam>[/xml]
の一文を書き加えています。この後出てくるプログラムでは、joint_state_publisherノード(Joint State Publisherウィンドウを管理しているノード)に各関節の関節角データを送り、それをjoint_state_publisherノードがrvizに送ることにより、モデルを動かしているのですが、ここをよく読むとわかる通り、それをするためには、joint_state_publisherが購読するトピックを指定してあげなければなりません。指定方法は、source_listというパラメータに、トピックの名前を書き込んであげればいいようです。付け加えた文では、このsource_listに/joint_states_sourceというトピック名を書き込んでいます。これにより、display.launchが実行されると、/joint_states_sourceを購読しながら、その値に応じたメッセージを/joint_statesに配信してくれるjoint_state_publisherが起動することになります。なお、この際、/joint_states_sourceトピックが存在していない場合は、自動で生成されるようです。

プログラムの作成

次に、プログラムを作成しましょう。
crane_urdf/srcにいる状態で、[php]vi reflect_crane_in_rviz.cpp[/php]と入力します。以下を貼り付けます。
[cpp]
#include "ros/ros.h"

#include "std_msgs/Float64.h"
#include "sensor_msgs/JointState.h"
#include "dynamixel_msgs/MotorStateList.h"

#include <sstream>

#define PI 3.14159265
#define MIDDLE_VAL 512
#define CHANGE_TO_DEG (300.0/1024.0)
#define CHANGE_TO_RAD (PI/180.0)

sensor_msgs::JointState jointstate;
char renew = 0;

void reflect_jointstate(const dynamixel_msgs::MotorStateList::ConstPtr& motorstates);

int main(int argc, char **argv)
{
ros::init(argc, argv, "reflect_crane_in_rviz");

ros::NodeHandle n;

ros::Publisher joint_states_pub = n.advertise<sensor_msgs::JointState>("/joint_states_source", 10);

ros::Subscriber sub = n.subscribe("/motor_states/pan_tilt_port", 10, reflect_jointstate);

ros::Rate loop_rate(100);

jointstate.name.push_back("joint1");
jointstate.name.push_back("joint2");
jointstate.name.push_back("joint3");
jointstate.name.push_back("joint4");
jointstate.name.push_back("joint5");
jointstate.position.push_back(0.0);
jointstate.position.push_back(0.0);
jointstate.position.push_back(0.0);
jointstate.position.push_back(0.0);
jointstate.position.push_back(0.0);

while (ros::ok())
{
while(ros::ok() && renew==0){
ros::spinOnce();
loop_rate.sleep();
}
jointstate.header.stamp = ros::Time::now();
joint_states_pub.publish(jointstate);
renew = 0;

ros::spinOnce();
loop_rate.sleep();
}
return 0;
}

void reflect_jointstate(const dynamixel_msgs::MotorStateList::ConstPtr& motorstates)
{
int id;
for(id=1;id<=5;id++){
jointstate.position[id-1] = ((double)(motorstates->motor_states[id-1].position)-MIDDLE_VAL)*CHANGE_TO_DEG*CHANGE_TO_RAD;
}
renew = 1;
}
[/cpp]
貼り付けたら、保存してviを終了してください。これがソースコードになります。今まで、ファイルを実行可能にする処理をしてきましたが、あれは別にいらなかったようなので、今回は飛ばします。
次に、
[php]
$ roscd crane_urdf
$ vi CMakeLists.txt
[/php]
と入力します。末尾に以下の3文を貼り付けます。
[php]
add_executable(reflect_crane_in_rviz src/reflect_crane_in_rviz.cpp)
target_link_libraries(reflect_crane_in_rviz ${catkin_LIBRARIES})
add_dependencies(reflect_crane_in_rviz crane_urdf_generate_messages_cpp)
[/php]
これで保存してviを終了してください。
次に、crane_urdfパッケージをビルドしましょう。
[php]
$ cd ~/catkin_ws/
$ catkin_make
[/php]
と入力します。「「100%」 Built target reflect_crane_in_rviz」と出てきていたら、ビルドが成功していると思います。

CRANE+とモデルの連動

以上で準備は整いました。第5回目の記事にしたがって、CRANE+とPCを接続し、今回は「roslaunch my_dynamixel_tutorial controller_manager.launch」
まで入力してください。「roslaunch my_dynamixel_tutorial start_tilt_controller.launch」まで入力してしまうと、CRANE+の関節角が固定されてしまい、手で動かせなくなるのでご注意ください。もしそうなった場合は、一回Ctrl-cを押してROSを終了してから、CRANE+の電源を切り、その後再度電源をいれ、操作をやり直してください。
その後、新しい端末を開いて、
[php]
$ roscd crane_urdf/src
$ roslaunch crane_urdf display.launch model:=crane.urdf
[/php]
と入力して、rvizを表示します。新しい端末を開き、
[php]rosrun crane_urdf reflect_crane_in_rviz[/php]
と入力すれば、rviz内のモデルが実物のCRANE+の状態を反映するようになります。けがやCRANE+の破壊に注意しながら、CRANE+の各関節を手で動かしてみてください。モデルとCRANE+が同じように動くと思います。なお、モデルに定義された回転角の限界以上まで関節を回すと、変な動きをしてしまいますが、ご容赦ください。

以上、CRANE+の状態をモデルに反映させる方法について説明しました。
次回は、CRANE+の状態をrviz上でモニタリングしつつ、CRANE+を自動で動かすプログラムを作ってみたいと思います。

ROSを使用したCRANE+の動かし方 その9

こんにちは!長谷川です。
前回はCRANE+のURDFモデルの作り方について説明しましたが、今回は、前回作ったモデルと実物のCRANE+の連動のさせ方について説明したいと思います。

プログラムの作成

まずは、モデルとCRANE+を連動させるプログラムを作成しましょう。端末を起動し、
[php]
$ roscd crane_urdf/src
$ vi reflect_rviz_in_crane.cpp
[/php]
と入力してviを起動します。以下を貼りつけます。
[cpp]
#include "ros/ros.h"

#include "std_msgs/Float64.h"
#include "sensor_msgs/JointState.h"

#include <sstream>

std_msgs::Float64 pos1;
std_msgs::Float64 pos2;
std_msgs::Float64 pos3;
std_msgs::Float64 pos4;
std_msgs::Float64 pos5;
char renew = 0;

void reflect_jointstate(const sensor_msgs::JointState::ConstPtr& jointstate);

int main(int argc, char **argv)
{
ros::init(argc, argv, "reflect_rviz_in_crane");

ros::NodeHandle n;

//publish command message to joints/servos of arm
ros::Publisher joint1_pub = n.advertise<std_msgs::Float64>("/tilt1_controller/command", 1000);
ros::Publisher joint2_pub = n.advertise<std_msgs::Float64>("/tilt2_controller/command", 1000);
ros::Publisher joint3_pub = n.advertise<std_msgs::Float64>("/tilt3_controller/command", 1000);
ros::Publisher joint4_pub = n.advertise<std_msgs::Float64>("/tilt4_controller/command", 1000);
ros::Publisher joint5_pub = n.advertise<std_msgs::Float64>("/tilt5_controller/command", 1000);

ros::Subscriber sub = n.subscribe("/joint_states", 10, reflect_jointstate);

ros::Rate loop_rate(100);
while (ros::ok())
{
while(ros::ok() && renew==0){
ros::spinOnce();
loop_rate.sleep();
}
joint1_pub.publish(pos1);
joint2_pub.publish(pos2);
joint3_pub.publish(pos3);
joint4_pub.publish(pos4);
joint5_pub.publish(pos5);
renew = 0;

ros::spinOnce();
loop_rate.sleep();
}
return 0;
}

void reflect_jointstate(const sensor_msgs::JointState::ConstPtr& jointstate)
{
pos1.data = jointstate->position[0];
pos2.data = jointstate->position[1];
pos3.data = jointstate->position[2];
pos4.data = jointstate->position[3];
pos5.data = jointstate->position[4];

renew = 1;
}
[/cpp]
これが、C++言語で書かれたソースコードになります。貼りつけたら、保存してviを終了してください。その後、
[php]chmod +x reflect_rviz_in_crane.cpp[/php]
と入力して、ファイルを実行可能にしておきましょう。
次に、
[php]
$ roscd crane_urdf
$ vi CMakeLists.txt
[/php]
と入力します。末尾に以下の3文を貼りつけます。
[php]
add_executable(reflect_rviz_in_crane src/reflect_rviz_in_crane.cpp)
target_link_libraries(reflect_rviz_in_crane ${catkin_LIBRARIES})
add_dependencies(reflect_rviz_in_crane crane_urdf_generate_messages_cpp)
[/php]
これで保存してviを終了してください。
次に、crane_urdfパッケージをビルドしましょう。
[php]
$ cd ~/catkin_ws/
$ catkin_make
[/php]
と入力します。「Linking ~」と書かれた一文の後に、「「100%」 Built target reflect_rviz_in_crane」と出てきていたら、ビルドが成功していると思います。

CRANE+とモデルの連動

これで準備は整ったので、CRANE+を実際に動かしてみましょう。第5回目の記事にしたがって、CRANE+とPCを接続し、「roslaunch my_dynamixel_tutorial start_tilt_controller.launch 」まで入力してください。
その後、
[php]
$ roscd crane_urdf/src
$ roslaunch urdf_tutorial display.launch model:=crane.urdf gui:=True
[/php]
と入力して、rvizとJoint State Publisherウィンドウを表示します。新しい端末を開き、
[php]rosrun crane_urdf reflect_rviz_in_crane[/php]
と入力すれば、実物のCRANE+がモデルの状態を反映するようになります。けがやCRANE+の破壊に注意しながら、Joint State Publisherウィンドウのバーを動かしてみてください。モデルとCRANE+が同じように動くと思います。
※天板上で動くので、天板にPC等を置くのは危険です。
※関節の可動範囲は最低限しか制限していないので、アームの先端が天板に当たったり、リンク同士がぶつかる可能性があります。CRANE+を破壊したり、けがをすることがないよう、無理のない速度と範囲で動かしてください。
※関節に指を挟まないよう注意してください。

プログラムの解説

今回のプログラムには、第7回目の記事で解説していない部分があるので、そこを説明したいと思います。
[cpp firstline=”32″]ros::Subscriber sub = n.subscribe("/joint_states", 10, reflect_jointstate);[/cpp]
ここで、/joint_statesというトピックを購読することを宣言しています。このトピックに新しいメッセージが来ると、reflect_jointstate()が呼び出されます。10というのは蓄えることのできるデータの最大数で、第7回で説明したものと同じ意味です。
なお、この/joint_statesには、Joint State Publisherが関節角を配信しており、そのトピックをrvizが購読して、取得した関節角をモデルに反映させることで、GUIでモデルを動かせるようになっています。このプログラムは、その仕組みを利用し、関節角をrvizとは独立して取得してCRANE+に反映させることで、CRANE+をrviz内のモデルと同じように動かしています。
[cpp firstline=”54″]void reflect_jointstate(const sensor_msgs::JointState::ConstPtr& jointstate)[/cpp]
この関数が呼び出された際、自動的に引数に新しいメッセージの内容が引き渡されます。つまり、sensor_msgs::JointState型のポインタjointstateの指し示すインスタンスには、新しいメッセージの内容が格納されています。
[cpp firstline=”56″]pos1.data = jointstate->position[0];[/cpp]
jointstate->position[0]には、モデルのjoint1の関節角が格納されています。それをpos1.dataに格納し、メイン文でpos1を/tilt1_controller/commandに配信することで、CRANE+のjoint1の関節角に反映します。

以上、前回作ったモデルと実物のCRANE+の連動のさせ方について説明しました。
次回は、CRANE+の状態をモデルに反映させる方法について説明したいと思います。

ROSを使用したCRANE+の動かし方 その8

こんにちは!長谷川です。
前回はROSのプログラムの書き方について説明しましたが、今回はCRANE+のURDFモデルの作り方について説明したいと思います。

URDFモデルとは

URDFとはUnified Robot Description Formatの略で、ロボットの形状や関節軸構成などのハードウェア情報を、XMLという形式で記録したものです。パッケージそのものの説明はこちらにあります。モデルの作り方についてのWikiはこちらにあるので、これをもとに説明を進めて行きたいと思います。

CRANE+のモデルについて

CRANE+の関節軸構成を以下のように分析し、名前付けします。
ROS_CRANE_8_0
これに基づき、モデルを構成していきます。なお、座標系は右手系です。

パッケージ、ファイルの作成

解説は後回しにして、まずは実際にモデルを作ってみましょう。端末を起動して、
[php]
$ cd ~/catkin_ws/src
$ catkin_create_pkg crane_urdf std_msgs rospy roscpp sensor_msgs
[/php]
と入力し、crane_urdfパッケージを作ります。この作業は今回のURDFモデル作成自体とは関係ありません。以前作成したturtlebot_armパッケージなどの上でモデルを作ることも可能ですが、次回紹介するプログラムを動かすためにはsensor_msgsに依存したパッケージを作らなければならないので、今回することにしました。
次に、
[php]
$ cd crane_urdf/src
$ vi crane.urdf
[/php]
と入力してviを起動します。編集モードに入り、以下を貼り付けます。
[xml]
<?xml version="1.0"?>
<robot name="crane">

<link name="base_link">
<visual>
<origin xyz="0 0 0.0227" rpy="0 0 0" />
<geometry>
<box size="0.0499 0.032 0.0454" />
</geometry>
<material name="red">
<color rgba=".8 0 0 1" />
</material>
</visual>
</link>

<joint name="joint1" type="revolute">
<parent link="base_link"/>
<child link="link1"/>
<origin xyz="0.0145 0 0.0454" rpy="0 0 0" />
<axis xyz="0 0 1" />
<limit lower="-2.61" upper="2.61" effort="0.5" velocity="6.0" />
</joint>

<link name="link1">
<visual>
<origin xyz="0 0 0.013" rpy="0 0 0" />
<geometry>
<box size="0.024 0.0475 0.026" />
</geometry>
<material name="red" />
</visual>

<visual>
<origin xyz="0 0 0.026" rpy="1.57079632675 0 0" />
<geometry>
<cylinder radius="0.012" length="0.0475" />
</geometry>
<material name="red" />
</visual>
</link>

<joint name="joint2" type="revolute">
<parent link="link1"/>
<child link="link2"/>
<origin xyz="0 0 0.026" rpy="0 0 0" />
<axis xyz="0 1 0" />
<limit lower="-1.75" upper="1.75" effort="0.5" velocity="6.0" />
</joint>

<link name="link2">
<visual>
<origin xyz="0 0 0" rpy="1.57079632675 0 0" />
<geometry>
<cylinder radius="0.012" length="0.0475" />
</geometry>
<material name="red" />
</visual>

<visual>
<origin xyz="0 0 0.0415" rpy="0 0 0" />
<geometry>
<box size="0.024 0.0475 0.083" />
</geometry>
<material name="red" />
</visual>

<visual>
<origin xyz="0 0 0.083" rpy="1.57079632675 0 0" />
<geometry>
<cylinder radius="0.012" length="0.0475" />
</geometry>
<material name="red" />
</visual>
</link>

<joint name="joint3" type="revolute">
<parent link="link2"/>
<child link="link3"/>
<origin xyz="0 0 0.083" rpy="0 0 0" />
<axis xyz="0 -1 0" />
<limit lower="-2.55" upper="2.55" effort="0.5" velocity="6.0" />
</joint>

<link name="link3">
<visual>
<origin xyz="0 0 0" rpy="1.57079632675 0 0" />
<geometry>
<cylinder radius="0.012" length="0.0475" />
</geometry>
<material name="red" />
</visual>

<visual>
<origin xyz="0 0 0.04675" rpy="0 0 0" />
<geometry>
<box size="0.024 0.0475 0.0935" />
</geometry>
<material name="red" />
</visual>

<visual>
<origin xyz="0 0 0.0935" rpy="1.57079632675 0 0" />
<geometry>
<cylinder radius="0.012" length="0.0475" />
</geometry>
<material name="red" />
</visual>
</link>

<joint name="joint4" type="revolute">
<parent link="link3"/>
<child link="link4"/>
<origin xyz="0 0 0.0935" rpy="0 0 0" />
<axis xyz="0 -1 0" />
<limit lower="-1.80" upper="1.80" effort="0.5" velocity="6.0" />
</joint>

<link name="link4">
<visual>
<origin xyz="0 0 0" rpy="1.57079632675 0 0" />
<geometry>
<cylinder radius="0.012" length="0.0475" />
</geometry>
<material name="red" />
</visual>

<visual>
<origin xyz="0 0 0.0227" rpy="0 0 0" />
<geometry>
<box size="0.024 0.0475 0.061" />
</geometry>
<material name="red" />
</visual>

<visual>
<origin xyz="0 0.03295 0.065727241" rpy="-0.52359878 0 0" />
<geometry>
<box size="0.034 0.0014 0.019" />
</geometry>
<material name="red" />
</visual>

<visual>
<origin xyz="0 0.0377 0.09665" rpy="0 0 0" />
<geometry>
<box size="0.034 0.0014 0.0454" />
</geometry>
<material name="red" />
</visual>
</link>

<joint name="joint5" type="revolute">
<parent link="link4"/>
<child link="link5"/>
<origin xyz="0 -0.0145 0.045" rpy="0 0 0" />
<axis xyz="-1 0 0" />
<limit lower="-0.69" upper="0.69" effort="0.5" velocity="6.0" />
</joint>

<link name="link5">
<visual>
<origin xyz="0 0 0" rpy="0 1.57079632675 0" />
<geometry>
<cylinder radius="0.012" length="0.0475" />
</geometry>
<material name="red" />
</visual>

<visual>
<origin xyz="0 -0.013 0" rpy="0 0 0" />
<geometry>
<box size="0.0475 0.026 0.024" />
</geometry>
<material name="red" />
</visual>

<visual>
<origin xyz="0 -0.0267 0.023" rpy="0 0 0" />
<geometry>
<box size="0.034 0.0014 0.070" />
</geometry>
<material name="red" />
</visual>

<visual>
<origin xyz="0 -0.0166252378 0.07545" rpy="-0.52359878 0 0" />
<geometry>
<box size="0.034 0.0014 0.040299" />
</geometry>
<material name="red" />
</visual>
</link>

</robot>
[/xml]
これがURDFモデルを記述した内容になります。貼りつけたら、保存してviを終了してください。これでモデル作成は完了です。

モデルの確認

次に、作成したURDFファイルが正しいフォーマットになっているか確認してみましょう。まず、
[php]sudo apt-get install liburdfdom-tools[/php]
と入力し、チェックのためのコマンドをインストールします。次に、
[php]check_urdf crane.urdf[/php]
と入力すると、以下のように表示されました。
ROS_CRANE_8_2
これで、正しいフォーマットになっていることが確かめられました。
そこで、
[php]roslaunch urdf_tutorial display.launch model:=crane.urdf[/php]
と入力すると、rviz(ROSのビジュアライザ)が起動し、何やら表示されます。
ROS_CRANE_8_3
拡大すると、以下のようにロボットモデルができていることがわかります。
ROS_CRANE_8_4
赤と緑と青の棒は、各関節のx,y,z軸を表しています。白い文字でlinkの名前も書かれていますね。ですが、これでは見にくいので、「Displays」欄内の「TF」に入っているチェックを外します。すると、以下のように、CRANE+を模したモデルができていることがわかります。
ROS_CRANE_8_5
あまりCRANE+に似ていないモデルですみません・・・。色も赤一色ですし・・・。このモデルは、私がURDFファイルの書き方の練習用に作ったものなので、書きやすい直方体と円筒のみで構成され、なんとなく外形を似せている状態です。あくまで練習用なので、ご容赦ください。
端末にCtrl-Cを打ち込んででrvizを終了し、今度は
[php]roslaunch urdf_tutorial display.launch model:=crane.urdf gui:=True[/php]
と入力してみてください。
ROS_CRANE_8_6
今までのrvizの他に、Joint State Publisherなるウィンドウが表示されたと思います。ここに表示されたバーを動かすことで、モデルの各関節を動かすことができます。
ROS_CRANE_8_7

URDFファイルのデータ構造

モデルの表記の仕方について、crane.urdfを見つつ学びましょう。
[xml firstline=”2″]<robot name="crane">[/xml]
[xml firstline=”194″]</robot>[/xml]
この二つに囲まれた部分で、一体のロボットが宣言されます。「crane」の所には他の名前を入れても機能します。
[xml firstline=”4″]<link name="base_link">[/xml]
[xml firstline=”14″]</link>[/xml]
リンク名「base_link」を定義したのち、この二つに囲まれた部分でリンクの状態を定義しています。リンク名はロボット内で唯一のものでなければなりません。なお、base_linkはロボット全体の中心となるリンクであり、必須のリンクとなっています。
[xml firstline=”5″]<visual>[/xml]
[xml firstline=”13″]</visual>[/xml]
この中で、リンク(この行ではbase_link)内の一つの物体についてのビジュアルを定義しています。
[xml firstline=”6″]<origin xyz="0 0 0.0227" rpy="0 0 0" />[/xml]
「xyz=”」の右には、根元のジョイントを原点とした時の、記述している物体の中心のxyz座標[m]を記入します。「rpy=”」の右には、物体を回転させる角度を記入します。
[xml firstline=”7″]<geometry>[/xml]
[xml firstline=”9″]</geometry>[/xml]
この中で、物体の形状を定義します。
[xml firstline=”8″]<box size="0.0499 0.032 0.0454" />[/xml]
記述している物体が、x方向に0.0499[m],y方向に0.032[m],z方向に0.0454[m]の厚みを持つ直方体であると定義しています。
[xml firstline=”10″]<material name="red">[/xml]
[xml firstline=”12″]</material>[/xml]
materialタグは、物体の表面の見栄えを定義するタグです。ここでは、この中で宣言された見栄えを「red」と定義することも同時に宣言しています。
[xml firstline=”11″]<color rgba=".8 0 0 1" />[/xml]
ここで、表面の色を定義しています。この数字だと赤色になるようです。
[xml firstline=”16″]<joint name="joint1" type="revolute">[/xml]
[xml firstline=”22″]</joint>[/xml]
ジョイント名「joint1」を定義したのち、この二つに囲まれた部分でジョイントの状態を定義しています。ジョイント名はロボット内で唯一のものでなければなりません。「type=”」の右には、ジョイントの種類を記入します。ジョイントの種類は以下のように定義されています。
revolute・・・ヒンジ機構
continuous・・・無限回転機構
prismatic・・・直動機構
fixed・・・固定関節
floating・・・自由関節
planar・・・水平移動機構
今回はrevolute、つまりヒンジ機構としています。
[xml firstline=”17″]<parent link="base_link"/>[/xml]
ジョイントの根元にあるリンク(親リンク)がbase_linkであると定義しています。
[xml firstline=”18″]<child link="link1"/>[/xml]
ジョイントの先にあるリンク(子リンク)がlink1であると定義しています。
[xml firstline=”19″]<origin xyz="0.0145 0 0.0454" rpy="0 0 0" />[/xml]
「xyz=”」の右には、親リンクの原点を基準とした、記述しているジョイントのxyz座標[m]を記入します。ここで、親リンクの原点とは、親リンクが最初のリンク(今回はbase_link)の場合はロボットモデル全体の原点、それ以外の場合は親リンクの根元のジョイントの位置を指します。「rpy=”」の右には、ジョイントを最初から回転させる角度を記入します。
[xml firstline=”20″]<axis xyz="0 0 1" />[/xml]
「xyz=”」の右には、回転関節の場合の回転軸の方向を記入します。回転軸の方向に進む右ねじが回る向きを正として、関節が回ることになります。
[xml firstline=”21″]<limit lower="-2.61" upper="2.61" effort="0.5" velocity="6.0" />[/xml]
ここでは、関節のリミットを設定しています。関節がrevoluteやprismaticの場合は、下限値にあたるlowerと、上限値にあたるupperを設定する必要があります。単位は、revoluteの場合は[rad]、prismaticの場合は[m]となっています。
effortとは、ジョイントが発揮できるトルク[Nm]または力[N]の絶対値の最大値のことです。今回は、0.5Nm以上のトルクを発揮できないよう制限されているということになります。
velocityとは、ジョイントの動く速度[m/s]または角速度[rad/s]の絶対値の最大値のことです。今回は、6.0rad/s以上の角速度で動かないよう制限されているということになります。
[xml firstline=”30″]<material name="red" />[/xml]
これは、先ほど定義した「red」という見栄えを物体の見栄えとすることを宣言しています。
[xml firstline=”36″]<cylinder radius="0.012" length="0.0475" />[/xml]
これは、記述している物体が半径0.012[m]、長さ0.0475[m]の円筒であると定義しています。ちなみに、
[xml]<sphere radius="1"/>[/xml]
と書くと、半径1[m]の球となります。また、
[xml]<mesh filename="package://pr2_description/meshes/gripper_v0/l_finger.dae" scale="1."/>[/xml]
などと、ファイルに記述された形状を反映させることも可能です。ファイル形式は、Colladaの.dae形式(推奨)と、.stl形式がサポートされています。

以上で、データ構造の基本は説明できたと思います。これ以上はこの記事では扱わないことにします。
その他の物理パラメータの設定方法や、拡張形式xacroの話については、チュートリアルの続きをご覧になってください。
また、シュミレータGazeboにモデルを読み込ませるためには、ファイルを変更しなければなりません。こちらをご覧になってください。

以上、CRANE+のURDFモデルの作り方について説明しました。
次回は、今回作ったモデルと実物のCRANE+の連動のさせ方について説明したいと思います。

ロボカップジャパンオープン@ホーム SPLリーグについて

はじめまして、今月からブログの執筆を担当させて頂くことになった新高校3年生の出村と申します!普段はロボットソフトウエアの研究開発をしています!
robocupjr5
saint10号


2011~2014年まではロボカップジュニアサッカーリーグに参加していまして、10台ほどサッカーロボットを開発してきました!
IMG_20141116_105203
Kenseiko-chan 2 Mobile つくばチャレンジ走行機(Turtlebotは秋の季節でも屋外を走ることが可能)

2014年からは生活支援ロボットの研究開発をしています。RoboCupJapanOpen2014@ホームシミュレーションリーグ、つくばチャレンジ2014やIntelligent Home Robotics Challengeに出場しています。
最近は人類の空を飛ぶ夢を叶えるゲーム Drone Space Defenceの開発をしています!

「ROSを使用したCRANE+の動かし方」のブログ記事読者に朗報があります! 今年の5/2~4に福井で開かれるロボカップジャパンオープンで新競技「ロボカップ@ホームSPLリーグ」が開催されます!皆さん、この大会には「ROSを使用したCRANE+の動かし方」で紹介したロボットで出場することができます!出村も出場します!http://www.robocupathomespl.org/home/robots(※日本語版の情報は古く、英語版が最新です)
RoboCup@home

ロボカップ@ホームとは


この競技を一言で表すと「ドラえもんを実現する」競技です!競技会には個性豊かなロボット達が集まります!自律型ロボットに人間と同じように家事をすることを可能にすることが目的の競技です!
RoboCup@Home Japan公式ページから引用:
「ロボカップ@ホームはロボカップ@のリーグの一つで、人と共に作業を行うロボットが,キッチンやリビングルームなどの家庭環境において様々な課題に取り組み,その達成度を競うことことを目的としています。
日常生活で人間を支援する自律ロボットによる競技を通じて,人とコミュニケーションしながら,より役に立つ仕事を行う実用的なロボットの実現を目指しています。」

ロボカップ@ホームSPLリーグとは

turtlebot_spl
ロボカップ@ホームSPLリーグはロボカップ@ホームで標準の同一なロボットプラットフォームを使うことが試みの新ロボット競技です。 ロボット@ホームSPLリーグでは同一なロボットプラットフォームを使うことだけでなく、選手達がロボットプラットフォームの変更/改造を通してよりよいロボットを生み出すことにより、実用的な生活支援ロボットプラットフォームを生み出すことが目標です。

ルール概要

毎年、標準のロボットプラットフォームが指定されます。 ハードウェアの改造/変更はSPLの技術評価を通していれば可能です。 ハードウェアの改造/変更は、生活支援ロボットプラットフォームの発展に貢献するので推奨されています。しかし、改造の技術的利点を競技の結果を通して証明する必要があります。良い変更/改造をした場合は表彰され次年度のロボットプラットフォームの設計に考慮されます。

基本的なハードウエア

特に明記されていない限り、ロボカップ@ホームのルールに準拠します (特にRoboCup@Home rulebook 2014の3.3節 ロボットに準拠します).


TutleBot (http://www.turtlebot.com/)を基本的なロボットプラットフォームとして指定します。 TurtleBotは低コストの個人向けのロボットキットでオープンソースソフトウエアのROS(Robot Operating System)に対応しています。
Turtlebotは以下の理由からロボットプラットフォームに選択されています。
1. ドキュメントとチュートリアルがそろっており(特にhttp://wiki.ros.org/Robots/TurtleBot等), ロボカップ@ホームのタスクを再現することが簡単です.  http://wiki.ros.org/turtlebot_follower/Tutorials/Demo
2. ユーザーが多く活発的なオープンソースコミュニティです。
3. 通常のロボカップ@ホームのタスクと比べ費用コストが小さく多くのところで販売されています。RTでも販売しています!(写真をクリックするとRT Shopのリンクに飛びます)

モバイルプラットフォームについて


標準のTurtleBotの仕様に準拠します。(KobukiかCreate base, http://turtlebot.com/build.html参照) 公式のTurtlebotの仕様に明記されている組み立て方法に準拠します。

コンピュータの規定

自由です。複数のコンピュータの使用も可能です。

認識センサの規定



Kinect(Xbox 360)かXtion Pro Liveを搭載したものが標準です。 他のセンサとの置き換えは変更とみなされます。また、センサの配置位置も変更とみなされ、その配置にした術的説明をする必要があります。 センサの増量は追加としてみなされます.

マニピュレータ


CRANE+

TurtleBotのアーム(http://wiki.ros.org/turtlebot_arm)が推奨されます。
CRANE+ (http://www.rt-shop.jp/index.php?main_page=product_info&cPath=1&products_id=2441)、 PhantomX Pincher Robot Arm Kit (http://www.trossenrobotics.com/p/PhantomX-Pincher-Robot-Arm.aspx) も可能です。 アームの取り付け位置は自由です。これ以外の場合は追加としてみなされます。

変更/追加の評価基準

以下の評価基準に基づいて変更/追加が可能です: 技術的正当性がTDP (Team Description Paper)とOpen Challengeで証明されなければいけません。 もし変更/追加にかかるコストが標準プラットフォームの費用コストの半分を超える場合、変更/追加のコストの正当性を示す必要があります。 もし変更/追加が技術委員会のInnovation Awardに選ばれた場合、ロボットの変更/追加に関する文書は、次年度のロボットプラットフォームの確立のために、再現性が証明された状態で公開する必要があります.

競技のルール

ロボカップ@ホームリーグ2014のルールがベースになっています。
4種類の競技があります。
ルールブック(英語)

1. Basic Functionalities

※5.2節のBasic Functionalities (pg. 40-42)参照
5.2.1節の 1. Pick and Place (pg. 40)について。 ロボットが拾うための物体はロボットアームの可動範囲内に配置されます。

2. Follow Me


※5.3節 Follow Me (pg. 43-47)参照
ルールの変更はありません。

3. Restaurant


※6.3節のRestaurant (pg. 64-66)参照
6.3.2節の, 1. Guide phase (pg. 64)は省きます。物体と配達する位置についての情報が試合前に与えられます。
6.3.2節の 2. Navigation and manipulation phase (pg. 64)について。 ロボットが回収する物体はロボットアームの可動範囲に配置されます。

4. Open Challenge


このビデオの4:50から〜
※5.5 Open Challenge (pg. 52-54)参照
ルールの変更はありません。

最後に

ロボカップ@ホームSPLリーグは新競技なので誰にでも優勝するチャンスがあります!ロボットが好きな方はロボカップ@ホームSPLリーグに今回参加してみてはどうでしょうか!またこれから出村がRoboCup@home SPLのロボットについてのブログを執筆しますので今後ともよろしくお願いします!