techno_memo

個人用の技術メモ。python・ROS・AI系のソフトウェア・ツールなどの情報を記載

ROS入門 ワークスペース/パッケージ/ノード (python開発環境/vscode導入)

この記事の目的

pythonを用いたROSのパッケージの作成・ノードの実装・トピックの送受信についてまとめる。 Visual studio Codeを導入し、pythonスクリプトを実装しやすい環境を構築する。

pythonを用いたROSプロジェクト構築

ROSでは処理を実装して動作させるまでに下記のワークスペース/パッケージ/ノードを準備する必要がある。 以下に最低限のコマンドなどをまとめて記述する。

用語 内容
workspace ROSプロジェクト開発の作業用フォルダ
package 機能の集合体(開発時にmakeするプロジェクトの最小単位)
node プロセスとして相互にメッセージを通信する単位

1 ワークスペースの作成

下記チュートリアルに従ってcatkin_wsを作成する

wiki.ros.org

ターミナルを開きホームフォルダ直下にcatkin_wsを作成する ここで、setup.bashはcatkin_ws内に作成したパッケージの読み込みに必要となる設定である。下記スクリプトを記載しておくと起動時に自動的に読み込まれる。

$ mkdir -p ~/catkin_ws/src
# ホーム直下にcatkin_ws/srcを作成
$ cd ~/catkin_ws/src
# srcに移動
$ catkin_init_workspace
# ワークスペースの初期化を実施
$ cd ~/catkin_ws/
# catkin_wsに移動
$ catkin_make
# ワークスペースのビルドを実施
$ echo "source ~/catkin_ws/devel/setup.bash" >> ~/.bashrc
# bashrc にプロジェクトフォルダのsetup.bashを読み込む設定を追記
$ source .bashrc
#bashrcの読み込み (入力したときのみ必要。以降は起動時にbashrcから読み込まれる)

2 パッケージの作成

下記チュートリアルに従ってcatkin_ws内にパッケージを作成する

wiki.ros.org

$ cd ~/catkin_ws/src
# catkin_ws/srcに移動
$ catkin_create_pkg beginner_tutorials std_msgs rospy roscpp
# catkin_create_pkg [パッケージ名] [依存ライブラリ1] [依存ライブラリ2]...
#上記ではROSの標準メッセージ std_msgsとpython開発環境/C開発環境を読み込んでいる 

ここでパッケージ以下には下記のようなファイル・フォルダ構成としておく。(cmakelists.txtとpackage.xml以外は必要に応じて追加する)

フォルダ・ファイル名 説明
CMakeLists.txt パッケージ用のcmakeファイル(ビルドの依存関係の設定など)
package.xml rosプロジェクトの名前/依存関係を記載したファイル
include パッケージのヘッダファイル(外部公開用)
src C言語実装済みソフトウェア(使用するときのみ)
script python実装済みソフトウェア(使用するときのみ)
msg ユーザーが型定義するros message(使用するときのみ)
launch ユーザーが定義するlaunchファイル(使用するときのみ)

3 Visual Studio Codeの導入

上記まででプロジェクトの作成ができたので、pythonでのスクリプトを記述する。

pythonスクリプトの開発は標準インストールされているテキストエディタでもできるがVisual Studio Codeを用いるとコード補完などが動作するので効率が良い。

Ubuntu mate for Raspberry pi 用の Visual Studio Code のインストール手順

$ wget -qO - https://packagecloud.io/headmelted/codebuilds/gpgkey | sudo apt-key add -
#GPGキーの設定
$ sudo su
#管理者権限の付与
 . <( wget -O - https://code.headmelted.com/installers/apt.sh )
#インストール用スクリプトの読み込み

ただし、下記記事にあるようにUbuntu mate 16.04と最新バージョンのVS codeでは正しく動作しなかったので1.29にデグレした。

www.fabshop.jp

sudo apt-get install code-oss=1.29.0-1539702286 -y --allow-downgrades
#1.29へのデグレ
sudo apt-mark hold code-oss
#バージョンの固定 下記コマンドで解除可能
#sudo apt-mark unhold code-oss

実行後に下記の拡張機能を追加する。

f:id:sd08419ttic:20190625001709p:plain

上記設定後にコマンドパレットでpython2.7に切り替えるとVisual studio codeでROS対応したpythonコードを実行できる

下記チュートリアルに従ってtopicをノード間通信するpythonスクリプトを記述する。

wiki.ros.org

talker.py

#!/usr/bin/env python
# license removed for brevity
import rospy
from std_msgs.msg import String

def talker():
    pub = rospy.Publisher('chatter', String, queue_size=10)
    rospy.init_node('talker', anonymous=True)
    r = rospy.Rate(10) # 10hz
    while not rospy.is_shutdown():
        str = "hello world %s"%rospy.get_time()
        rospy.loginfo(str)
        pub.publish(str)
        r.sleep()

if __name__ == '__main__':
    try:
        talker()
    except rospy.ROSInterruptException: pass

listener.py

#!/usr/bin/env python
import rospy
from std_msgs.msg import String

def callback(data):
    rospy.loginfo(rospy.get_caller_id()+"I heard %s",data.data)
    
def listener():

    # in ROS, nodes are unique named. If two nodes with the same
    # node are launched, the previous one is kicked off. The 
    # anonymous=True flag means that rospy will choose a unique
    # name for our 'listener' node so that multiple listeners can
    # run simultaenously.
    rospy.init_node('listener', anonymous=True)

    rospy.Subscriber("chatter", String, callback)

    # spin() simply keeps python from exiting until this node is stopped
    rospy.spin()
        
if __name__ == '__main__':
    listener()

上記の2つのファイルを記述後にそれぞれのpythonファイルを実行するとtopic通信が行われることが確認できる。 次回はpythonジョイスティックやGUIを行いながらトピックの通信を行うスクリプトについて記述する。