ROSの基本的な開発
ROSのワークスペースを作る
ROSのワークスペースを作ります。以下のコマンドを入力してください。 また、ROSに関するツールを使えるようにするため、パスを通しておきます。
mkdir -p ros_ws/src cd ros_ws source /opt/ros/indigo/setup.bash
ここで一度makeしておきます。ROSではcatkin_makeというコマンドを使ってワークスペースのプロジェクトをビルドします。また、初回でこのコマンドを行えばワークスペースに必要なファイルやディレクトリが生成されます。
catkin_make
catkin_makeしたら以下のようなファイル階層になっていると思います。
ros_ws |--build |--devel |--src
- build
- ビルドに関する設定やmakeのlogのファイルが入っています。
- devel
- 実行ファイルやmakeによって生成されたものが入っています。
- src
- ユーザがソースコードを保存する場所です。
これでワークスペースはできました。
ROSパッケージを作る
ROSでは任意の機能をつめたソフトウェアの集合をパッケージと呼びます。 パッケージの雛型はcatkin_create_pkgで作成することができます。またcatkin_create_pkgのコマンド引数は以下のとおりです。
catkin_create_pkg [package_name] [depend1] [depends2] ...
コンソールに以下のコマンドを入力してください。
cd src catkin_create_pkg ros_adder roscpp rospy std_msgs
この場合、パッケージの名前はros_adder、また依存関係を持たせるパッケージはroscpp、std_msgs,sensor_msgsということになります。 ワークスペースでもう一度catkin_makeしましょう。
cd ~/ros_ws/ catkin_make
ROSのコーディング
ここではROSの具体的なコーディングを行います。
ROS message
ROSでは処理に必要なデータは基本的にメッセージとして通信を行ないます。 そのメッセージのデータ構造はさまざまなデータ型から任意のものを選択して独自のデータ構造にすることができます。 たとえば、データ型には以下のものがあります。
- int8, int16, int32, int64 (plus uint*)
- float32, float64
- string
- time, duration
- other msg files
- variable-length array[] and fixed-length array[C]
またメッセージに関するクラスが定義されているヘッダーは/opt/ros/indigo/include
内にあります。
簡単なメッセージファイルを作ってみましょう。
cd ~/ros_ws/src/ros_adder mkdir msg; cd msg touch Adder.msg emacs Adder.msg
メッセージファイルAdder.msgの中には以下の記述をしてください。 このmsgファイルでは32bitのsigned int型の変数を1個,sensor_msgs/Image型の変数を1個保有していることになります。
Adder.msg
int32 arg_x int32 arg_y
このメッセージファイルを元にメッセージ型を定義するヘッダファイルが生成されます。 ヘッダファイル生成の設定を行うため以下のファイルを編集してください。
cd ~/ros_ws/src/ros_adder emacs CMakeLists.txt
CMakeLists.txt
#該当意部分がはコメント解除して適宜修正 #7行目あたり find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs + message_generation ) #45行目あたり ## Generate messages in the 'msg' folder add_message_files( FILES - # Message1.msg - # Message2.msg + Adder.msg ) #66行目あたり generate_messages( DEPENDENCIES std_msgs ) #104行目あたり catkin_package( # INCLUDE_DIRS include LIBRARIES ros_adder CATKIN_DEPENDS roscpp rospy std_msgs DEPENDS system_lib )
catkin_makeしましょう。
cd ~/ros_ws catkin_make
catkin_makeに成功すると以下のディレクトリにメッセージを定義したPythonコードが生成されます。
ls ~/ros_ws/devel/lib/python2.7/dist-packages/ros_adder/msg/ _Adder.py __init__.py
ROSのノードを記述する
ROSのノードをPythonで記述していきます。
cd ~/ros_ws/src/ros_adder/ mkdir scripts; cd scripts touch para_in.py adder.py
- para_in.py:処理に必要なデータをPublishするPublisher
- adder.py:publisherから受け取ったデータを表示するSubscriber
Publisherを作る
以下に示すコードがPublisherとなります。
なお、コード中のAPIの説明などはコメントによって記しています。
para_in.py
#!/usr/bin/python # -*- coding: utf-8 -*- # license removed for brevity # pythonでROSのソフトウェアを記述するときにimportするモジュール import rospy # 自分で定義したmessageファイルから生成されたモジュール from ros_adder.msg import Adder def para_in(): # 初期化宣言 : このソフトウェアは"para_in"という名前 rospy.init_node('para_in', anonymous=True) # nodeの宣言 : publisherのインスタンスを作る # input_dataというtopicにAdder型のmessageを送るPublisherをつくった pub = rospy.Publisher('input_data', Adder, queue_size=100) # 1秒間にpublishする数の設定 r = rospy.Rate(5) para_x = 0 para_y = 2 # Adder型のmessageのインスタンスを作る msg = Adder() # ctl + Cで終了しない限りwhileループでpublishし続ける while not rospy.is_shutdown(): msg.arg_x = para_x msg.arg_y = para_y # publishする関数 pub.publish(msg) print "published arg_x=%d arg_y=%d"%(msg.arg_x,msg.arg_y) para_x += 1 para_y += 1 r.sleep() if __name__ == '__main__': try: para_in() except rospy.ROSInterruptException: pass
Subscriberをつくる
以下に示すコードがSubscriberとなります。 なお、コード中のAPIの説明などはコメントによって記し、Publisherと同じ部分のコメントは省いています。
adder.py
#!/usr/bin/python # -*- coding: utf-8 -*- # license removed for brevity import rospy from ros_adder.msg import Adder # Subscribeする対象のトピックが更新されたら呼び出されるコールバック関数 # 引数にはトピックにPublishされるメッセージの型と同じ型を定義する def callback(data): # 受けとったmessageの中身を足し算して出力 print data.arg_x + data.arg_y def adder(): rospy.init_node('adder', anonymous=True) # Subscriberとしてimage_dataというトピックに対してSubscribeし、トピックが更新されたときは # callbackという名前のコールバック関数を実行する rospy.Subscriber('input_data', Adder, callback) # トピック更新の待ちうけを行う関数 rospy.spin() if __name__ == '__main__': adder()
2つのファイルの記述が終わったら、ビルドしましょう。
cd ~/ros_ws/ catkin_make
ROSで作ったノードを実行してみる
ビルドが成功したら、さっそく実行してみましょう。 現在開いているコンソールほかにもう2つのコンソールを開き以下のコマンドを上からそれぞれ入力してください。
1つ目のコンソール
ROSではroscoreというコマンドを始めに起動することでさまざまなソフトウェアをスタートすることができます。
具体的にはroscoreはネームサービスなどを行います。
cd ~/ros_ws source devel/setup.bash roscore
2つ目のコンソール
ROSでは各ノードの実行はrosrunというコマンドによって実行されます。
ROSにおいて単体のノード実行は基本的にrosrunで行います。
subscriberを起動します。
cd ~/ros_ws source devel/setup.bash rosrun ros_adder adder.py
3つ目のコンソール
publisherを起動します。
cd ~/ros_ws source devel/setup.bash rosrun ros_adder para_in.py
起動に成功したら以下のような結果が得られます。
実行を止めたいときはCtrl + Cで止まります。
root@localhost:~/ros_ws# rosrun ros_adder para_in.py published arg_x=0 arg_y=2 published arg_x=1 arg_y=3 published arg_x=2 arg_y=4 published arg_x=3 arg_y=5 published arg_x=4 arg_y=6 published arg_x=5 arg_y=7 root@localhost:~/ros_ws# rosrun ros_adder adder 2 4 6 8 10 12 14
コマンドまとめ
- catkin_make - ワークスペース内のパッケージを一括ビルドするコマンド
- catkin_create_pkg - ROSにおけるパッケージの雛形を作るコマンド
- roscore - ROSのネームサービス、マスタ
- rosrun - ROSの単体ノードを起動する際に使用するコマンド