1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

WSL2 Python をつかって ROS2 をあつかってみよう

Last updated at Posted at 2024-10-10

 このドキュメントでは ROS2 で Python をつかいロボット(亀)を動かす方法を解説します。さっそくはじめましょう。

このドキュメントは以下の記事を事前に読み、作業を終えていることが前提として記述されています。

  • WSL と ROS2 のセットアップ

VScode から WSL 内のプログラムにアクセスできるようにする方法

 VScode から WSL 内のプログラムを直接編集、作成、実行できるようにすることで開発効率がとてもよくなります。ここでは VScode の拡張機能をインストールして WSL 内の資源を VScode 経由でアクセスできるようにする方法を解説します。

拡張機能をインストールする

 まずはじめに VScode を開いてください。スタートメニューから VScode と入力するといかのように VScode が候補に挙がりますので、「開く」をクリックして開いてください。

もし候補に VScode が上がらない場合は、お使いのコンピューターに VScode がインストールされていません。こちらの記事 を参考に VScode をインストールしてください。

ツールバー横に拡張機能一覧が表示されるので、検索バーに Japanese と入力してください。

 VScode が起動すると、左側にいくつかのアイコンが縦に並んでいるところがあります。ここを ツールバー といいます。ツールバーの下部に のようなアイコン (拡張機能) をクリックしてください。

 拡張機能 を開いて、検索バーに 「remote develop」 と入力してください。すると、 >< みたいなアイコンの拡張機能 「Remote Development」 をインストールしてください。

インストールボタンが「インストール済み」になったら成功です。また、ツールバーの拡張機能の下にモニターのアイコンが追加されます。

 このモニターアイコンをクリックすると、WSL 上に存在する Ubuntu に接続する設定が開きます。

 WSL TARGETS の部分に WSL 上にインストールされている Linux 一覧が表示されています。ログインしたい Linux の横にある 「→」 をクリックすると、現在作業しているウィンドウで Linux にログインします。

 Linux に無事ログインすると、VScode ウィンドウ左下の青い部分に WSL Ubuntu と表示されており、今作業している VScode で WSL Linux にログインしていることを表しています。

 これで VScode をつかって WSL 上のプログラムを編集する環境が整いました!使用している VScode を WSL からログアウトしたい場合、 WSL Ubuntu をクリックしてください。すると下の図のようにメニューが表示されるので、メニュー上でカーソルを下に回して一番下にある リモート接続を終了する をクリックしてください。

 ログアウトするとVScode ウィンドウ左下の青い部分の WSL Ubuntu >< になります。この状態が WSL からログアウトし、ホスト上にいることを示しています。

WSL2 Ubuntu を起動する

 まずはじめに WSL2 を起動して Ubuntu にログインしましょう。PowerShell を起動して以下のコマンドを実行しましょう。

wsl ~

 PowerShell の プロンプト緑色 に変化したら成功です。

プロンプトとは

 コマンドプロンプト、PowerShell、ターミナルなどのウィンドウでコマンドを入力する部分のことを指します。
 プロンプトの左端に表示される文字列のことを プロンプトストリングス(もしくは PS) といいます。OS、使用するコマンドの種類によって PS の表示内容が異なります。ほとんどの PS は現在どこのディレクトリで作業しているかを示す カレントディレクトリの絶対パス が記載されます。

  • PowerShell の場合
PS C:\your\path>
  • コマンドプロンプト の場合
C:\your\path>
  • ターミナル の場合
name@pc:/your/path$

ROS2 をかんたんにつかえるようにする Tips

 さて、ROS2 を使用するには以下のコマンドを実行しなければなりません。

source /opt/ros/humble/setup.bash

でもこれいちいちシェルと起動するたびにやるのって効率悪いですよね。ここではこのコマンドをいちいち実行しなくてもよくする方法をはじめに解説しましょう。

bashrc

 bashrc(バッシュアールシー)とは簡単に言うと起動されるシェルの設定を書く設定ファイルです。設定ファイルといってもプログラミングコードで記述されています。以下のコマンドを実行して bashrc の中身を見てみましょう。

code ~/.bashrc

 するとこのように VScode から ~/.bashrc の中身を見ることができます。

 ここに書かれているプログラミング言語は Bash(バッシュ)といいますが、これは要するに Linux で使用するコマンドを複数行かいたもの です。Linux のコマンドさえ覚えてしまえばそんなに難しくありません。試しにですが、以下のコマンドを ~/.bashrc の末尾に書いてみましょう。

echo "Welcome Ubuntu !"

 このコマンドは "" の中にかいた文字列を出力します。このコマンドを末尾に書いて、保存してみてください。

そしたらシェルに戻り、以下のコマンドを実行してください。すると ~/.bashrc が再読み込みされます。

source ~/.bashrc



すると、このようにシェルに先ほど入力した文字列が出力されています。
 また、一度 Ubuntu からログアウトしてもう一度ログインしてみましょう。


するとこのようにログイン時も文字列が出力されているのがわかるでしょう。このように ~/.bashrc に記述したコマンドなどは シェルにログインされるたびに実行される のです。これを活用すればいちいち

source /opt/ros/humble/setup.bash

を実行する必要がなくなるわけですよ(^^)


まぁ要するにコマンド source /opt/ros/humble/setup.bash~/.bashrc に書き込むことで面倒なしがらみから解放されるってことですね。VScode にこのコマンドを追記しましょう。

そしたら以下のコマンドを実行して ~/.bashrc を再読み込みしましょう。

source ~/.bashrc

つぎに ROS2 関連のコマンドを実行してみましょう。無事 ROS2 が扱えるようになるはずです。

ros2 topic list

これで ROS2 を簡単に扱えるようにする環境構築は完了しました。

turtlesim を起動しよう

 以下のコマンドを実行して turtlesim を起動しましょう。青色のウィンドウとカメが表示されたら成功です。以下のコマンドを実行してください。

ros2 run turtlesim turtlesim_node

このまま起動しているシェルは待機させて、次のセクションに進んでください。

VScode で Python を書くための環境を作る

 ここで で Ubuntu から直接 VScode を起動しましたが、このセクションでは改めて Windows から VScode を起動して VScode 経由から WSL2 Ubuntu にログインする方法を解説します。この方法も覚えておくことで効率的に今後開発することができるでしょう。

リモートデスクトップオプションの WSL ターゲットからインストール済みの Linux ディストリビューションを指定して VScode 経由からログインすることができます。

左下の青い部分に WSL:Ubuntu と表示されていたら成功です。この状態で拡張機能を開いて Python 拡張機能をインストールしてください。

これで WSL Ubuntu で Python 開発する準備が整いました。

亀を Python で動かしてみよう

 では亀を動かしてみましょう。そのためにはプログラムを書くファイルを作らなくてはいけませんね。VScode のツールバー上部にファイルエクスプローラーがあります。ここをクリックすると 「フォルダーを開く」 というボタンが表示されるのでここをクリックしてください。

次にこのように上部にどのフォルダ(ディレクトリ)を選択するのかを聞かれるので ~ などと入力してホームディレクトリを指定しましょう。決定したら 「OK」 をクリックしましょう。

すると、このようにホームディレクトリが VScode 左辺にエクスプローラとして表示されます。このエリアにあるフォルダに + アイコンがついているボタンをクリックすると、新規フォルダ(ディレクトリ)を作成することができます。試しに python_scripts という名前のディレクトリを作ってみましょう。

フォルダアイコンをクリックすると、このように入力欄があるので、ここにディレクトリ名を入力して、エンターキーを押すと。。。

このようにディレクトリが作成されます!

今度は作成したディレクトリを指定した状態でファイルに + アイコンがついたボタンをクリックして、新規ファイルを作成しましょう。

 するとこのようにファイル名を入力する項目が出るので、turtle_control.py というファイルを作成しましょう。この得必ず拡張子が .py でなければなりませんので気をつけてください。

 これで準備は完了です。turtle_control.py に亀を動かすプログラムを書いていきましょう。先に示すと、以下のコードを書くと亀が円を描きながら動いてくれます。

import rclpy
from rclpy.node import Node
from geometry_msgs.msg import Twist

def move_turtle():
    # rclpyを初期化
    rclpy.init()

    # Nodeを作成
    node = Node('turtle_controller')

    # Publisherを作成
    publisher = node.create_publisher(Twist, '/turtle1/cmd_vel', 10)

    # Twistメッセージを作成
    twist = Twist()

    # 速度を設定
    twist.linear.x = 1.0  # 前進速度
    twist.angular.z = 0.5  # 回転速度

    # ループでメッセージを送信
    try:
        while rclpy.ok():
            # メッセージをログに出力
            node.get_logger().info('Publishing: linear.x=%f, angular.z=%f' % (twist.linear.x, twist.angular.z))
            
            # メッセージを送信
            publisher.publish(twist)

            # 1秒待機
            rclpy.spin_once(node, timeout_sec=1.0)
    except KeyboardInterrupt:
        pass

    # ノードを破棄
    rclpy.shutdown()

if __name__ == '__main__':
    move_turtle()

実行するとこのように亀が動きます。

どうやって動かしているの?

 ここではサンプルで示した turtle_control.py のコードを解説します。まず注目するのは初めの 3 行です。

import rclpy
from rclpy.node import Node
from geometry_msgs.msg import Twist

ここでは3つのモジュール rclpyNodeTwist をインポートしています。それぞれのモジュールは以下の役割を持っています。

  • rclpy
    ROS2 を制御するための Python ライブラリです。
  • Node
    実行コード内で ROS2 ノードを生成し、ROS2 ネットワークに接続するための API。
  • Twist
    メッセージの型です。このオブジェクトにデータを入力し指定されたトピックに Publish することでロボットを動かすことができます。

次に、実行部分です。ロボットを制御しているプログラムは move_turtle という関数にまとめられているのがわかるでしょう。

def move_turtle():
    # rclpyを初期化
    rclpy.init()

    # Nodeを作成
    node = Node('turtle_controller')

    # Publisherを作成
    publisher = node.create_publisher(Twist, '/turtle1/cmd_vel', 10)

    # Twistメッセージを作成
    twist = Twist()

    # 速度を設定
    twist.linear.x = 1.0  # 前進速度
    twist.angular.z = 0.5  # 回転速度

    # ループでメッセージを送信
    try:
        while rclpy.ok():
            # メッセージをログに出力
            node.get_logger().info('Publishing: linear.x=%f, angular.z=%f' % (twist.linear.x, twist.angular.z))
            
            # メッセージを送信
            publisher.publish(twist)

            # 1秒待機
            rclpy.spin_once(node, timeout_sec=1.0)
    except KeyboardInterrupt:
        pass

    # ノードを破棄
    rclpy.shutdown()

関数 move_turtle 内の処理について解説しましょう。まず初めに

rclpy.init()

という処理があります。この処理はこのプログラムで ROS2 を扱うので rclpy の初期化を行います。これを最初に書かないとプログラム内で ROS2 を扱うことができずエラーが発生してしまいます。
 次に、以下の処理が行われます。

node = Node('turtle_controller')

これはなんなのかというと、このプログラム内で turtle_controller という名前のノードを宣言しています。ノードというのは ROS2 におけるプログラムの最小単位で、ノードが立つことでノード同士がデータをやり取りします。ノード同士のやり取りでロボットを動かしていくわけです。このコードは指定した名前のノードを宣言し、以降 ROS2 ネットワークに接続するために必要mなライブラリを提供してくれます。このような処置を インスタンス化 と言います。
 次に、以下の処理が行われます。

publisher = node.create_publisher(Twist, '/turtle1/cmd_vel', 10)

 インスタンス化された node には、create_publisher というメソッドが用意されています。このメソッドを使用することで指定されたトピック、メッセージ型にデータを送るためのインターフェースを作成してくれます。Publisher の設定は各引数で行われます。

  • 第1引数
    Publish するメッセージ型を指定します。ここでは Twist が指定されています。
  • 第2引数
    Publish するトピック名を指定します。ここでは /turtle1/cmd_vel が指定されています。
  • 第3引数
    QoS プロファイルを指定します。この段階ではなんなのかを知るとややこしくなるので 10 を入力してください。

 次に Twist メッセージにデータを入れるために Twist オブジェクトを以下の処理でインスタンス化します。

twist = Twist()

 そして、インスタンス化されたオブジェクトにデータを入力します。

# 速度を設定
twist.linear.x = 1.0  # 前進速度
twist.angular.z = 0.5  # 回転速度

コメントで示されている通り Twist.linear.x は前進速度を指定し、Twist.angular.z で回転速度を指定します。
 そして、以下の処理で設定した Twist データを Publish します。

# ループでメッセージを送信
try:
    while rclpy.ok():
        # メッセージをログに出力
        node.get_logger().info('Publishing: linear.x=%f, angular.z=%f' % (twist.linear.x, twist.angular.z))
        
        # メッセージを送信
        publisher.publish(twist)

        # 1秒待機
        rclpy.spin_once(node, timeout_sec=1.0)
except KeyboardInterrupt:
    pass

while rclpy.ok() とは、rclpy.ok()True の間は以下の処理を繰り返すという意味です。rclpy.ok() は ROS2 が動いている限り True を返し続けます。
 そして、以下の処理は ROS2 のロガー出力で、ログとしてメッセージを出力するコードです。

node.get_logger().info('Publishing: linear.x=%f, angular.z=%f' % (twist.linear.x, twist.angular.z))

 そして、重要なのはここです。

publisher.publish(twist)

ここでメッセージデータを格納した twist オブジェクトを create_publisher で指定したトピックへ Publish します。この処理によって亀が動くのです。

rclpy.spin_once(node, timeout_sec=1.0)

 この処理は ROS2 の反映を待機する関数です。これを書かないと publisher がうまく動いてくれません。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?