対象読者
- 実環境をpipで汚すのが嫌な人
- Ubuntu24.04を使っている人
- これからROS2、Mujocoを使おうとしている人
目次
初めに
「MujocoをROS2で動かしたい!」と思って仮想環境で構築を始めたのですが、この環境構築が非常に大変でした。個人的にはローカルが汚れてもまあいいかと感じるタイプなのですが、Ubuntu24ではそもそもローカルにpipで何かを入れることが禁止されており、仮想環境を使わざるを得ませんでした。
特に、Python仮想環境とROS2の相性の悪さが問題を引き起こし、解決するまで苦労しました。
本記事では、同じ構成を目指す方の参考になればと思い、手順と注意点を整理して共有します。
使用環境
以下の二つの環境で動作を確認しました。
Jazzy
言語・フレームワーク | バージョン |
---|---|
Python | 3.12.3 |
Mujoco | >=3.3.3 |
uv | 0.7.9 |
ROS2 | Jazzy |
Humble
言語・フレームワーク | バージョン |
---|---|
Python | 3.10.2 |
Mujoco | >=3.3.3 |
uv | 0.7.9 |
ROS2 | Humble |
なぜ相性が悪いのか?
ROS2のpythonパッケージは実環境に置かざるを得ないため
ROS 2とPython仮想環境の相性が悪いのは、両者のパッケージ管理の思想が根本的に対立するためです。
-
ROS 2: aptなどを使い、C++ライブラリも含めてシステム全体にパッケージをインストール
-
Python仮想環境: プロジェクトごとに依存関係をシステムから隔離
そのため、仮想環境でros2のコマンドを使用してPythonを実行すると、必ずどちらかのパッケージしか見つけることができないのです。
解決策
ROS 2とPython仮想環境の共存問題は、高速なパッケージマネージャuvの--system-site-packagesオプションを使って解決できます。
この方法は、仮想環境の「隔離性」を意図的に緩和し、aptでインストールされたシステムワイドなROS 2のPythonパッケージを、仮想環境内から参照できるようにするものです。
この手法であれば、ROS2で外部パッケージを自由に使いつつ、実環境をクリーンなままにすることが可能です。
具体的な手法
# 1. 仮想環境のPythonのバージョンを実環境と合わせる
uv python pin 3.xx
# 2. --system-site-packages を付けて仮想環境を作成
uv venv --system-site-packages .venv
# 3. 仮想環境とROS 2の環境を有効化
source .venv/bin/activate
source /opt/ros/humble/setup.bash
# 4. mujocoをインストール & 適用
uv add mujoco
uv sync
すでに仮想環境を構築してしまった場合は、uv.lock
と.venv
以下を全て消した上で上記の工程を行ってください。
パッケージのビルド時の注意
Pythonをビルドする時にもament_cmakeを使うことを推奨します。少なくともJazzyを使用して開発を行っているときは、ament_pythonを使用したパッケージをビルドすることはできませんでした。
ROS2ではPythonパッケージをビルドする際にsetup.py
に設定を記述し、python setup.py install
のような形で設定を適用します。しかし、最近のアップデート(2022年くらい?)でこの記法が非推奨になったらしく、この方法は現在エラーを吐いてしまいます。
そこで、CMakeを利用してビルドを行います。具体的には、以下のように記述します。
CMakeList.txt
cmake_minimum_required(VERSION 3.8)
project(package_name)
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()
# find dependencies
find_package(ament_cmake REQUIRED)
find_package(ament_cmake_python REQUIRED)
find_package(rclpy REQUIRED)
# uncomment the following section in order to fill in
# further dependencies manually.
# find_package(<dependency> REQUIRED)
# 自作パッケージのインストール
ament_python_install_package(${PROJECT_NAME}_libs PACKAGE_DIR libs)
# Python package installation
install(PROGRAMS scripts/joint_state_calculator_node.py
DESTINATION lib/${PROJECT_NAME})
# スクリプトのインストール
install(PROGRAMS scripts/unitree_g1_controller_node.py
DESTINATION lib/${PROJECT_NAME})
if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
# the following line skips the linter which checks for copyrights
# comment the line when a copyright and license is added to all source files
set(ament_cmake_copyright_FOUND TRUE)
# the following line skips cpplint (only works in a git repo)
# comment the line when this package is in a git repo and when
# a copyright and license is added to all source files
set(ament_cmake_cpplint_FOUND TRUE)
ament_lint_auto_find_test_dependencies()
endif()
ament_package()
コードを書く際、libディレクトリやutilsを作成してコードを整頓したくなる場合は多いと思いますが、ビルド時にスクリプトはsrc/installにコピーされてディレクトリ構成が変化するので、そのままでは自作モジュールを発見できません。そこで、libディレクトリやutilsをライブラリとしてインストールする必要があります。(実体はワークスペース以下にあるので実環境は汚れません)
ament_python_install_package(${PROJECT_NAME}_libs PACKAGE_DIR libs)
についてですが、これは(パッケージのあるディレクトリ)/libs以下を全てpythonパッケージとしてライブラリ化するということです。
コーディングの際には
先ほどの手法でビルドを行うと、src/install
以下に自分のライブラリやスクリプトが置かれます。そのため、そのままではVSCodeがライブラリを認識できず補完が全く効きません。そこで、設定
->Python › Auto Complete: Extra Paths
に追加することでVSCodeにライブラリを認識させます。
"python.analysis.extraPaths": [
"/(ws_path)/src/install/(package_name1)/lib/python3.12/site-packages",
"/(ws_path)/src/install/(package_name2)/lib/python3.12/site-packages"
],
私の場合はこんな感じで追加しました。ディレクトリがよくわからないときは、
python
>> import (your_package)
>> (your_package).__file__
とすると、パッケージの実体がどこにあるかわかるので、その一つ上のディレクトリを選択すると、
from (your_package) import hoge
みたいな使い方をした時に適切に補完を出すことができます。
参考記事