目次 このページのソースコードを表示

Pipenv上でROS2ノードを動かす

公開日:
更新日:

Pipenv仮想パッケージ環境上でROS2ノードを動かす.

はじめに

ROS2でノードを実装するときに, PythonかC++を使います. Python では, すでに公開されている多くのパッケージを使ってノードを実装することができます. ですが, ROS2をaptコマンドでインストールした際, ROS2のPythonパッケージはシステムのグローバル環境上にインストールされ, そのほかのパッケージを使うときも必然的にグローバル上にインストールしなければなりません.

本稿では, Pipenv仮想パッケージ環境上でROS2ノードを動かす方法を説明します.

ハックな方法です

このやり方は, 公式ではなく, 結果的にうまくいった方法です.

Pipenv とは

Pipenv は, パッケージの追加と削除に加えて, パッケージの仮想環境の作成と管理を行えるツールです[1].

"Pipenv: 人間のためのPython開発ワークフロー". Pipenv. accessed at 2020-08-28.

主な特徴としては,

  • パッケージの管理ツールであるpipと, 仮想環境の管理ツールであるvirtualenvを別々に使う必要はなく, 両者は連携して動作
  • ほかの人の仮想環境をPipfileを通じて, 同じ環境を構築可能
  • pyenvをインストールすることで, インタプリタの切り替えも可能

です.

pyenv, virtualenv, pip, pipenvの機能を表にまとめると以下の通りです.

機能比較
インタプリタ管理 仮想環境管理 パッケージ管理
pyenv o x x
virtualenv x o x
pip x x o
pipenv △(pyenvと連携) o o

このように比較すると, Pipenvは非常に優秀なツールであることが分かります.

環境構築

  1. Pipenvのインストール
                pip install pipenv --user
    
  2. ROS2のインストール

    公式ドキュメントを参考してください(この記事を読んでいる時点で, もう入っていると思います).

    "ROS 2 Documentation". ROS2. accessed at 2020-08-28.

環境

本稿では, 以下の環境のもとで行っています.

  • Ubuntu 20.04.1 LTS
  • ROS 2 Foxy Fitzroy
  • pipenv, version 2020.8.13

方法

仮想環境を構築する

まず, ROS2のワークスペースが以下のようであるとします.

  • workspace
    • src
      • package-1
      • package-2

workspace内に, pipenv のPipfileを入れるためのディレクトリenvを作成します.

  • workspace
    • env
    • src
      • package-1
      • package-2

envに移動後, pipenv installを行い, 仮想環境を構築します.

            cd env
            pipenv install
注意

ここで, Pythonバージョンを指定してはいけません. システムPythonを使用するようにします.

理由

ROS2は, あくまでシステムPythonを使用します.

ROS2ノードがシステムPythonを使用する以上, 仮想パッケージ環境のインタプリタもシステムPythonを使用しましょう.

他の人からもらったPipfileでPythonバージョンを指定されているのだが…

Pipfile内で, このようにPythonバージョンが指定されている場合.

                    [requires]
                    python_version = "3.6"

残念ながら, システムPythonのバージョンと異なるバージョンで動かすことはできません.

ですが, メジャーバージョンのみ合わせればいいのならば, 対応可能です. (逆にマイナーバージョンの指定はできません.)

pipenv install時に, 以下のようにPythonバージョンを指定します.

                    pipenv install --python 3

ワークフロー

ROS2 のパッケージビルドを行う

仮想環境に入らずにビルドをします.

workspace移動後, 以下のコマンドでビルドします.

                colcon build
なぜ, 仮想環境でやらないの?

本稿では, 仮想環境上でROS2ノードを動かすのを目的としています. 実際に仮想環境上にあるパッケージが使用されるのは, ROS2ノードが実行しているときのはずです.

colcon は, システムPythonのパッケージを使用しており, ビルド時まで仮想環境上で動かして, エラーが出るリスクを侵したくありません.

ROS2ノードを仮想環境で実行する

ROS2ノードの実行スクリプト(Pythonスクリプト)が仮想環境にあるパッケージを必要とするときは, 仮想環境上でROS2ノードを実行しなければなりません.

まず, ROS2環境を読み込みましょう.

                source /opt/ros/foxy/setup.zsh  

envディレクトリに移動後, 以下のコマンドで, 仮想環境のシェルに入ります.

                pipenv shell

上のコマンドを実行後, 次のようなメッセージが表示されたはずです.

                ~/o/h/s/p/S/env ❯❯❯ pipenv shell                                                                  master
                Warning: Your Pipfile requires python_version 3.6, but you are using 3.8.2 (/home/ken/.local/share/v/e/bin/python).
                  $ pipenv --rm and rebuilding the virtual environment may resolve the issue.
                  $ pipenv check will surely fail.
                Launching subshell in virtual environment…
                 . /home/ken/.local/share/virtualenvs/env-nmD9sybt/bin/activate

大事なのは, 次の行です.

                 . /home/ken/.local/share/virtualenvs/env-nmD9sybt/bin/activate

このメッセージが意味するのは, 仮想環境を/home/ken/.local/share/virtualenvs/env-nmD9sybt/bin/activateでアクティベートしたことです.

そして, 仮想環境で使用されるパッケージは, /home/ken/.local/share/virtualenvs/env-nmD9sybt/lib/python3.8/site-packagesにあります. (実際に確認してみてください. パス内にあるpython3.8は各自の環境で異なる可能性があります.)

ですが, このままROS2ノードを実行しても, 仮想環境上のPythonインタプリタが実行されるのではなく, システムPyhtonを実行することになり[注 1], 仮想環境にあるパッケージをシステムPythonが見つけることができません.

よってすることは, システムPythonがこれらパッケージを見つけられるように, PYTHONPATHにパッケージのパスを追加することです.

以下のコマンドを実行します.

                PYTHONPATH=$PYTHONPATH:~/.local/share/virtualenvs/env-nmD9sybt/lib/python3.8/site-packages 
なぜexportしないの?

なぜこうしないのか?

                    export PYTHONPATH=$PYTHONPATH:~/.local/share/virtualenvs/env-nmD9sybt/lib/python3.8/site-packages 
理由

仮想環境を出たあとに, PYTHONPATHは, 仮想環境に入る前に戻って欲しいから.

別ターミナルでパッケージのビルドを行ったあと, ディレクトリworkspaceで, パッケージのインストールを行い(筆者は, zshを使ってます),

                . install/setup.zsh

ノードを実行します.

                ros2 run <package-name> <node-name>

注釈

  1. ^ 実際は, システムのPyhtonインタプリタにシンボリックリンクが貼られていて, リンクを通らずにそのまま, 直接システムPythonを呼んでいることになります[注 2].
  2. ^ たぶん。。。

参考文献

「https://contentsviewer.work/Master/ROS2/Tips/with-pipenv/with-pipenv」から取得