0
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 をあつかってみよう

Posted at

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

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

  • WSL と ROS2 のセットアップ

  • VScode のインストールとセットアップ

  • WSL と VScode の連携

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 がうまく動いてくれません。

0
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
0
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?