Pythonバインディングのバックエンド

概要

ChoreonoidのPythonバインディングは、C++のクラスや関数をPythonから利用できるようにするためのバインディングライブラリを用いて実装されています。このライブラリのことを、ここではバインディングのバックエンドと呼びます。

Choreonoidでは現在、バックエンドとして以下の2種類を選択できるようになっています。

バックエンド

内容

nanobind

nanobind を用いた実装です。現在のデフォルトで、ソースは src/*/python ディレクトリに格納されています。後述のfree-threaded Pythonに対応しています。

pybind11

pybind11 を用いた従来の実装です。ソースは src/*/pybind11 ディレクトリに格納されています。

nanobindはpybind11の作者が同じ設計思想のもとで新たに開発したライブラリで、pybind11と比べてバイナリサイズやビルド時間、実行時のオーバーヘッドが削減されています。またfree-threaded Pythonに対応しているという利点もあります。

現在はnanobindへの移行期にあたるため両方のバックエンドを選択できるようになっていますが、移行が完了した時点でpybind11のバックエンドは削除される予定です。通常はデフォルトのnanobindをそのまま使用してください。

両方のバックエンドに存在するモジュールについては、Pythonから見えるクラス・関数のインタフェースが基本的に同じになるように実装されています。したがって、通常のスクリプトを記述する上でどちらのバックエンドであるかを意識する必要はありません。

ただし、提供されるモジュールの集合は完全に同一ではありません。新しく追加されたプラグインのモジュールにはnanobind版のみが用意されているものがあり、2026年8月時点ではBulletプラグイン、MuJoCoプラグイン、PhysXプラグインのモジュールがこれに該当します。pybind11のバックエンドではこれらのモジュールはビルドされません。

バックエンドの切り替え

バックエンドはCMakeのオプション CHOREONOID_PYTHON_BINDING_BACKEND で切り替えます。値として nanobind (デフォルト)か pybind11 を指定します。

pybind11のバックエンドを使用する場合は、CMakeの設定で以下のように指定します。

cmake -DCHOREONOID_PYTHON_BINDING_BACKEND=pybind11 ..

このオプションはCMakeのキャッシュ変数となっており、一度設定した値はビルドディレクトリに保存されます。既存のビルドディレクトリでバックエンドを切り替える場合は、上記のように値を明示的に指定してCMakeを再実行してください。値を指定せずにCMakeを実行した場合は、キャッシュに保存されている以前の値がそのまま使用されます。

注釈

バックエンドを切り替えると、生成されるPythonモジュールのバイナリが入れ替わります。切り替えの前後で古いモジュールが残っていると予期しない動作の原因となるため、切り替える際にはビルドディレクトリを新規に作成することをおすすめします。

free-threaded Pythonの利用

free-threaded Pythonとは

CPythonには従来、Global Interpreter Lock(GIL)と呼ばれる排他制御の仕組みがあり、複数のスレッドが同時にPythonのコードを実行することができませんでした。このため、マルチスレッドのプログラムを記述しても、Pythonコードの実行に関しては並列化による高速化が得られないという制約がありました。

Python 3.13以降では、このGILを無効化した free-threaded ビルドが提供されています。free-threaded Pythonを使用すると、複数のスレッドでPythonコードを真に並列に実行できるようになります。Choreonoidにおいても、例えば複数のロボットモデルに対する処理をスレッドで並列化するといった使い方が可能となります。

Choreonoidのnanobindバックエンドはこのfree-threaded Pythonに対応しています。pybind11のバックエンドは対応していないため、free-threaded Pythonを利用する場合はnanobindのバックエンドを使用する必要があります。

注釈

pybind11のバックエンドでは、後述するfree-threaded Pythonの自動検出も行われません。仮にfree-threaded版のインタプリタを明示的に指定してビルドしたとしても、生成されるモジュールはGILを使用しないことを宣言しないため、モジュールの読み込み時にGILが有効化されます。

free-threaded Pythonのインストール

free-threaded版のPythonは、通常版とは別のインタプリタとして提供されます。実行ファイル名はバージョン番号の末尾に "t" を付けた python3.13tpython3.14t といった名前になっており、通常版と共存させることができます。

Ubuntuでのインストール

Ubuntuの標準のリポジトリでは、現状free-threaded版のPythonは提供されていません。そこで deadsnakes PPA を利用します。まずこのPPAをシステムに追加します。

sudo add-apt-repository ppa:deadsnakes/ppa

パッケージのリストを更新します。

sudo apt update

このPPAで利用できるPythonのバージョンは、Ubuntuのバージョンによって異なります。以下のコマンドで、利用可能なfree-threaded版のパッケージを確認してください。

apt search nogil

free-threaded版のパッケージは python3.13-nogil のように、通常版のパッケージ名に "-nogil" が付いた名前になっています。ここで表示されたバージョンの中から使用するものを選びます。どのバージョンを選ぶかについては、後述の「使用するPythonのバージョンの選択」を参照してください。

以下ではPython 3.13を使用する場合を例として説明します。他のバージョンを使用する場合は、コマンド中の "3.13" の部分を読み替えてください。まずインタプリタ本体をインストールします。

sudo apt install python3.13-nogil

これにより /usr/bin/python3.13t がインストールされます。さらに、Choreonoidのビルドに必要な開発用のヘッダとライブラリ、および仮想環境の作成に必要なパッケージをインストールします。

sudo apt install libpython3.13-nogil libpython3.13-dev python3.13-venv

注釈

libpython3.13-nogil にはfree-threaded版のライブラリ本体と pyconfig.h が含まれますが、 Python.h をはじめとする共通のヘッダは libpython3.13-dev の側に含まれます。そのため、両方をインストールする必要があります。また python3.13-venv には後述の仮想環境の作成に必要な ensurepip モジュールが含まれており、これが無いと仮想環境を作成できません。

なお、使用しているUbuntuのバージョンがこのPPAの対象となっていない場合や、必要なバージョンのパッケージが提供されていない場合は、Pythonのソースからビルドしてインストールすることもできます。この場合はconfigureの際に --disable-gil オプションを指定します。

使用するPythonのバージョンの選択

free-threaded版のPythonを利用する場合、単に最も新しいバージョンを選べばよいとは限らない点に注意が必要です。ChoreonoidのPython機能はNumPyを使用しますが、後述するようにNumPyのfree-threaded版に対応したパッケージは、Pythonのバージョンごとに提供状況が異なるためです。新しすぎるバージョンのPythonを選ぶと、対応するNumPyが存在せずに利用できないという状況になり得ます。

したがって、以下の手順でバージョンを選ぶことをおすすめします。

  1. apt search nogil で、インストール可能なPythonのバージョンを確認する

  2. PyPIのNumPyのページ で、それらのバージョンに対応するwheelが提供されているかを確認する(ファイル名の cp313t のような部分がPythonのバージョンに対応します)

  3. 両方の条件を満たすバージョンのうち、最も新しいものを選ぶ

参考として、2026年8月時点における状況は以下の通りです。ただしこれらの状況は随時変化しますので、実際には上記の手順で確認してください。

Ubuntuのバージョン

PPAで提供されるPython

NumPyが対応するもの

24.04

3.13 / 3.14 / 3.15

3.13 / 3.14

25.04 / 25.10

提供なし

26.04

3.13 / 3.15

3.13

例えばUbuntu 26.04ではPython 3.13とPython 3.15がインストール可能ですが、Python 3.15に対応するNumPyのwheelはまだ提供されていないため、Python 3.13を選択することになります。

Windowsでのインストール

Python公式サイト のインストーラを実行し、インストールオプションのカスタマイズ画面でfree-threaded版のバイナリをインストールする項目を選択します。この項目の有無や名称はPythonのバージョンによって異なりますので、詳細はPythonの公式ドキュメントを参照してください。

free-threaded Pythonを用いたビルド

nanobindのバックエンドが選択されている場合、CMakeはfree-threaded Pythonを自動で検出し、それが見つかればビルドに使用します。検出の対象となるのは /usr/local/bin/usr/bin/bin の各ディレクトリにある python3.*t という名前の実行ファイルで、候補が複数ある場合は名前の順序が後のもの(通常はバージョン番号が最も大きいもの)が優先されます。候補は実際にfree-threadedビルドであるかどうかを問い合わせて確認した上で採用されます。

これら以外の場所にインストールしたインタプリタは自動検出の対象とならないため、その場合は後述の Python_EXECUTABLE で明示的に指定してください。

検出の結果は、CMakeの実行時に以下のようなメッセージとして出力されます。free-threaded Pythonが使用される場合は次のように表示されます。

-- Using a free-threaded (no-GIL) Python: /usr/bin/python3.13t (3.13.14)

free-threaded Pythonが見つからず、通常のPythonが使用される場合は次のように表示されます。

-- Using a standard (GIL-enabled) Python: /usr/bin/python3 (3.14.4)

ビルドに使用するインタプリタを明示的に指定したい場合は、CMakeの変数 Python_EXECUTABLE にそのパスを設定します。

cmake -DPython_EXECUTABLE=/usr/bin/python3.13t ..

この変数が設定されている場合は自動検出は行われず、指定されたインタプリタがそのまま使用されます。

逆に、free-threaded Pythonがインストールされている環境で、あえて通常のPythonを使用したい場合は、オプション DISABLE_FREE_THREADED_PYTHON をONにします。

cmake -DDISABLE_FREE_THREADED_PYTHON=ON ..

このオプションは上記の自動検出を行わないようにするもので、その結果としてCMakeの通常のPython検出処理が選択するインタプリタが使用されます。したがって、システムの標準のPythonがfree-threaded版である環境では、このオプションをONにしてもfree-threaded版が使用されることになります。同様に、このオプションと Python_EXECUTABLE を同時に指定した場合は、指定したインタプリタが優先されます。

注釈

Choreonoid本体とPythonバインディングは、ここで選択されたインタプリタのABIに対してビルドされます。free-threaded版と通常版ではABIが異なるため、ビルドに使用したものと異なる種別のインタプリタからモジュールを読み込むことはできません。使用するインタプリタを変更する場合は、ビルドディレクトリを新規に作成してビルドし直してください。

free-threaded Pythonでの実行

free-threaded Pythonを用いてビルドした場合、Choreonoidに内蔵されるPythonインタプリタもfree-threaded版となり、GILが無効化された状態で動作します。 Pythonコンソール やPythonスクリプトアイテムから実行するスクリプトも、この内蔵インタプリタ上で実行されます。

CPythonでは、GILを使用しないことを宣言していない拡張モジュールが読み込まれると、実行時にGILが自動的に有効化されるという仕様になっています。ChoreonoidのPythonモジュールはnanobindの機能によりGILを使用しないことを宣言しているため、これらのモジュールを読み込んでもGILは無効のまま維持されます。

ただし、NumPyをはじめとする外部のPythonライブラリについては、それぞれのライブラリがfree-threaded Pythonに対応している必要があります。対応していないライブラリを読み込むと、その時点でGILが有効化され、並列実行の効果が得られなくなります。この場合でもスクリプト自体は問題なく動作します。

仮想環境とNumPyの準備

ChoreonoidのPython機能はNumPyを使用しますが、Ubuntuの python3-numpy パッケージは通常版のPython向けにビルドされているため、free-threaded版のPythonからは利用できません。free-threaded版に対応したNumPyは、PyPIで配布されているwheelをpipでインストールします。

このためのPythonの仮想環境(venv)を、free-threaded版のインタプリタから作成します。

python3.13t -m venv ~/python-ft

作成した仮想環境を有効化します。

source ~/python-ft/bin/activate

この状態でNumPyをインストールします。

pip install numpy

注釈

NumPyのfree-threaded版のwheelは、Pythonのバージョンごとに提供状況が異なります。使用しているPythonのバージョンに対応するwheelがNumPyの最新版に無い場合は、pipが自動的に対応する版まで遡ってインストールします。例えば2026年8月時点では、Python 3.13に対応するwheelはNumPy 2.4.6までが提供されているため、最新版の2.5.1ではなく2.4.6がインストールされます。対応するwheelが全く存在しない場合は、pipがソースからのビルドを試みて失敗します。その場合は、前述の「使用するPythonのバージョンの選択」を参照して、対応するPythonのバージョンを選び直してください。

インストールが正しく行われたかどうかは、以下のスクリプトで確認できます。

python -c "import sys, numpy; print(numpy.__version__, sys._is_gil_enabled())"

NumPyのバージョンに続いて False と表示されれば、NumPyを読み込んだ状態でもGILが無効のまま維持されており、正しく動作しています。 True と表示される場合は、インストールされたNumPyがfree-threaded版に対応していません。

Choreonoidからの利用

上記の仮想環境を有効化した状態でChoreonoidを起動すると、Choreonoidに内蔵されたPythonインタプリタもその仮想環境を認識し、そこにインストールされているライブラリを利用できるようになります(この機能はUbuntu等のUNIX系OSで有効です)。

注釈

内蔵インタプリタが仮想環境を利用するのは、仮想環境内にChoreonoidがリンクしているPythonのバージョンと種別に対応するライブラリのディレクトリ( lib/python3.13t 等)が存在する場合に限られます。存在しない場合は、その仮想環境がChoreonoidのリンクしているPython向けのものではない旨の警告が出力され、仮想環境は使用されません。これは、異なるABI向けにビルドされたネイティブの拡張モジュールを読み込んでクラッシュすることを防ぐための仕様です。

Pythonスクリプト機能の概要 の「Choreonoid外部のPythonからの利用」で解説しているように、Choreonoidを起動せずに外部のPythonからモジュールを利用することもできます。この場合も、上記の仮想環境を有効化した状態で実行してください。

python script.py