はじめに
お疲れ様です。秋並です。
pybulletはpythonで使用できる物理エンジンの一つで、ロボティクスや機械学習などの分野に使用されています。
pybulletでは、以下のリポジトリにて公式のサンプルが用意されています。
一方で、pybulletのサンプルコードは129個(pythonコード128個+inoコード1個)と大量に存在します。
また、サンプルコードについて解説しているようなサイトも見当たりませんでした。
そこで、せっかくなので私が
全ての公式サンプルを解説
したいと思います。
pybulletの公式サンプルコードは学習に役立つものもたくさんあるため、この記事を読むことで、
pybulletで何ができるかを知ることができる
と思っているので、是非ご覧ください。
pybulletの公式サンプル一覧
以下が公式サンプルの一覧になります。
解説記事が投稿されているコードは、コード名をクリックするとその記事に飛ぶようになっています。
コード名 | 概要 | 実行動画 |
---|---|---|
addPlanarReflection.py | ray機能を使って、マウスでクリックしたオブジェクトの色を変える | |
batchRayCast.py | ray機能を使用した2DLiDARの模擬 | |
biped2d_pybullet.py | ランダムな凸凹した地形を生成し、その上に二足歩行ロボットを生成する | |
changeDynamicsMass.py | 2つのオブジェクトを読み込み、片方の動力学特性を変更する | |
changeTexture.py | オブジェクトのテクスチャを動的に変更する | |
collisionFilter.py | 読み込んだ「床」と「ボックス」間の衝突を有効化する | |
commandLogAndPlayback.py | 実行したシミュレーションデータをログファイルに保存したのちに、そのログファイルを読み込みシミュレーションを再現する | |
configureDebugVisualizer.py | 光源の位置を時間とともに変化させる | |
constraint.py | オブジェクトが回転しながら、直線上を行ったり来たりする | |
contactFriction.py | ボックスに生じる法線力と横方向の摩擦力を計算し、(ターミナル上に)表示 | |
createMesh.py | 複数のオブジェクトを生成し、追従するカメラで撮影する | |
createMultiBodyBatch.py | 大量のオブジェクトを計算効率が最適化されたモードで生成する | |
createMultiBodyLinks.py | 複数の物体に、プロパティを設定し生成する | 後日gif画像追加予定 |
createObstacleCourse.py | 複数のオブジェクトを生成し、追従するカメラで撮影する | 後日gif画像追加予定 |
createSphereMultiBodies.py | 寺院のモデル内に、球体と立方体の衝突物体を生成する | |
createTexturedMeshVisualShape.py | ray機能を使用して、マウスでクリックした物体の色を変える | 後日色が変わることが分かる動画に変更予定 |
createVisualShape.py | オブジェクトを生成する | |
createVisualShapeArray.py | 複数のオブジェクトを生成する | |
debugDrawItems.py | kukaのiiwaロボットアームを動かし、先端に「tip」と表示する | |
deformable_add_remove_objects.py | 布を生成する (マウスで操作すると布と分かりやすい) |
後日、布のオブジェクトと分かりやすいgifに変更予定 |
deformable_anchor.py | ボックスと布を生成し、布の各頂点を表示する | 後日、布と分かりやすいgif画像に変更予定 |
deformable_ball.py | 剛体のボックスとソフトボディのボールを生成する | |
deformable_torus.py | 剛体のボックスとソフトボディのドーナツ状の物体を生成する | |
draw_frames.py | ボックスの様々な参照フレームを可視化する | |
dumpLog.py | ログファイルを読み取り、その内容を解析する | pybulletは使用されません。 そのまま実行すると、 FileNotFoundError: [Errno 2] No such file or directory: 'log.bin' と表示され実行できないため、適当なログファイルを用意する必要があります |
dumpVrLog.py | VRシミュレーションのログファイルを読み取り、ボタンの状態を解析する | pybulletは使用されません。 そのまま実行すると、 FileNotFoundError: [Errno 2] No such file or directory: 'data/example_log_vr.bin' と表示され実行できないため、適当なログファイルを用意する必要があります |
eglRenderTest.py | EGLプラグインを使用し、取得したカメラ画像をオフスクリーンレンダリングする |
DIRECT モードで実行されるため、gui画面は表示されません |
experimentalCcdSphereRadius.py | 地面と球状のオブジェクトを複数生成し、接触情報を(ターミナル上に)表示する 1 | 後日動画変更予定 |
externalTorqueControlledSphere.py | 球体をキーボードでコントロールし、球体に追従するようにカメラを動かす | 後日動画変更予定 |
fileIOPlugin.py | 外部プラグインを使用し、ZIPファイルからオブジェクトをロードし表示する | |
forcetorquesensor.py | 力/トルクセンサを有効化し、ジョイントの状態を取得する | guiモードで起動しますが、一瞬で終了します |
frictionCone.py | 複数のボールに異なる初速度を設定し、軌道を確認する | 後日、複数のボールの動画に変更予定 |
getAABB.py | オブジェクトの軸平行境界ボックス(AABB)を表示する | |
getCameraImageTest.py | 様々なレンダリングで画像を撮影し、結果をmatplotlibで表示する | |
getClosestPoints.py | 球とボックス間の最短距離を可視化する | |
getTextureUid.py | 床のテクスチャを変更して、一定時間経過したらテクスチャを元に戻す | |
graphicsClient.py |
別ターミナルで、grapcServer.pyを起動した状態で実行したください p.GRAPHICS_SERVER_TCP モードでpybulletを起動し、ロボットを生成する |
実行内容が graphicsServer.py で起動したgui画面に反映されます |
graphicsServer.py |
GRAPHICS_SERVER モードでpubulletを起動する |
|
grpcClient.py | ローカルまたはリモートのGRPCサーバーに接続し、ロボットを生成する | 私の環境では、AttributeError: module 'pybullet' has no attribute 'GRPC' と表示され実行できませんでした |
grpcServer.py | GRPCプラグイン使用してシミュレーションを実行する | 私の環境では、Cannot load grpcPlugin と表示され実行できませんでした |
hand.py | VR用のハンドコントローラから得られたセンサデータをもとに、シミュレーション上のハンドを制御する | 実機のハンドコントローラが必要ですが、私が所持していないため実行できていません。 |
hand.ino | Arduino用のファイル。 ピンから取得した値を表示する | - |
heightfield.py | 3種類の方法で複雑な地形を生成する 2 | |
hello_pybullet.py | オブジェクトを生成する | |
humanoid_benchmark.py | ヒューマノイドを読み込んで、シミュレーションを実行し、パフォーマンスのベンチマークをpybullet_humanoid_timings.json に出力する。3
|
DIRECT モードで実行されるため、gui画面は表示されません |
humanoid_knee_position_control.py | guiのスライダーを使用して、ヒューマノイドロボットの膝を制御する | |
humanoid_manual_control.py | guiスライダーを使用して、ヒューマノイドロボットの各関節を制御する | |
humanoidMotionCapture.py | 5種類のPD制御により、ヒューマノイドロボットの動作を制御する | |
ik_end_effector_orientation.py | 逆運動学を使用して、kukaのiiwaロボットアームのエンドエフェクタを指定した位置/姿勢に制御する | 後日gif画像追加予定 |
integrate.py | ボックスを1秒間落下させ、ボックスの最終位置/姿勢をターミナルに表示します | guiモードで起動しますが、一瞬で終了します |
internalEdge.py | 床の上に小さなオブジェクトを生成し、接触情報を(ターミナル上に)表示する 4 | |
inverse_dynamics.py | トルク制御を実行し、その結果をmatplotlibで描画する ※コードにバグがあるのか、私の環境ではmatplotlibの結果が正常に表示されていません |
|
inverse_kinematics_husky_kuka.py | 「移動ロボットhusky」に「kukaのiiwaロボットアーム」を搭載したモデルを使用して、逆運動学でロボットアームの手先が円を描くように制御する | |
inverse_kinematics_pole.py | Sawyerロボットアームを制御し、軌道を描画する | |
inverse_kinematics.py | kukaのiiwaロボットアームで、逆運動学を使用して、手先が円を描くように制御する | |
inverted_pendulum_tendon_actuation.py | 弦で作動する逆振り子の PID 制御を行い、制御結果をmatplotlibで描画する | |
jacobian.py | ヤコビ行列を計算する | gui画面は表示されず、計算結果がターミナル上に表示されます |
jointFrictionAndMotor.py | トルク制御されているドアのパラメータをguiスライダーで動的に変更する | |
jointFrictionDamping.py | 速度制御されているモータのパラメータを、guiスライダーで動的に変更する | |
kuka_grasp_block_playback.py | 「kukaのiiwaロボットアームで物体をつかむ」シミュレーションデータが保存されたログファイルを読み込み、guiスライダーでステップごとにシミュレーションを再現する | |
kuka_with_cube_playback.py |
kuka_with_cube.py で実行されたシミュレーションのログファイルを読み込み、同じシミュレーションを再現する |
後日gif画像追加予定 |
kuka_with_cube.py | 逆運動学を使用し、エンドエフェクタの位置を周期的に更新する 実行したシミュレーションはログファイルに保存される |
後日gif画像追加予定 |
load_soft_body.py | 剛体のボックスと、ソフトボディのウサギを生成する | |
loadingBench.py | 性能評価のベンチマークに使用されるような大規模なオブジェクトを生成する | |
logMinitaur.py | 四足歩行ロボットを生成し、ロボットの状態をLOG00048.TXT に出力する |
gif画像追加予定 |
manyspheres.py | 複数の球体を生成し、guiスライダーで重力方向を変更する | |
mimicJointConstraint.py | ジョイント間で設定された歯車比で、回転を同期させる | |
minitaur_evaluate.py | 四足歩行ロボットminitaurの動作を評価するための関数がまとめられたコード |
minitaur_test.py で使用されるコードであるため、単体では動作しません |
minitaur_test.py | 四足歩行ロボットminitaurを制御し、その制御結果を評価する | |
minitaur.py | 四足歩行ロボットminitaurをモデル化し制御するためのクラスが定義されているコード |
minitaur_test.py で使用されるコードであるため、単体では動作しません |
motorMaxVelocity.py | カートポール制御を行い、制御時の「位置」と「速度」をターミナル上に表示する | |
otherPhysicsEngine.py | PhysXとよばれるbulletとは別の物理エンジンを使用し、ドミノ倒しをシミュレーションする | 設定が足りていないのか、私の環境ではAttributeError: module 'pybullet' has no attribute 'PhysX' と表示され実行できませんでした |
pdControl.py | 複数のpdコントローラでカートポールを制御する。 ※ guiスライダーでパラメータを動的に変更可能 |
|
pdControllerExplicit.py | 「PDコントローラ」を定義したコード |
pdControl.py で使用するため、単体では動作しません |
pdControllerStable.py | 「安定したPDコントローラ」を定義したコード |
pdControl.py で使用するため、単体では動作しません |
pointCloudFromCameraImage.py | 取得した画像情報をもとに、ポイントクラウドを生成する | |
profileTiming.py | シミュレーションを実行し、タイミングイベントをログファイルsingle_step_no_stepsim_chrome_about_tracing.json に記録する |
後日gif画像追加予定 |
projective_texture.py | オブジェクトを生成し、テクスチャを適用(なぜかテクスチャ適用部分がコメントアウトされている) | |
quadruped_playback.py | ログファイルLOG00076.TXT を読み込み、四足歩行ロボットのシミュレーションを再現する |
SHARED_MEMORY モードで実行されるためguiは表示されません |
quadruped_setup_playback.py | 四足歩行ロボットを読み込み、制約を設定する |
SHARED_MEMORY モードで実行されるためguiは表示されません |
quadruped.py | 四足歩行ロボットをシミュレーションする | 私の環境では、gui画面が表示されませんでした |
racecar_differential.py | 移動ロボットを生成し、guiスライダーで速度などを制御する | |
racecar.py | スタジアムの環境に移動ロボットを生成し、guiスライダーで速度などを制御する | |
reduced_deformable_cube.py | 変形するボックスの上から剛体のボックスを落とす | |
reduced_deformable_torus.py | 変形するドーナツ状のオブジェクトと、剛体のボックスを2台ずつ生成する | |
renderPlugin.py | r2d2を生成し、追従するカメラで画像を撮影する | |
rendertest_sync.py | 複数のレンダリングでミュレーションを実行し、パフォーマンス(FPS)を計測する | 私の環境ではAttributeError: module 'tensorflow' has no attribute 'set_random_seed' と表示され、実行できませんでした |
rendertest.py | 複数のレンダリングでミュレーションを実行し、パフォーマンス(FPS)を計測する matplotlibでリアルタイムの画像を表示する |
|
reset_dynamic_info.py | 特定の物体の慣性ボックス(慣性モーメントを視覚的に表すボックス)を描画する | 私の環境ではAttributeError: module 'pybullet' has no attribute 'DYNAMICS_INFO_REPORT_INERTIA' と表示され実行できませんでした |
restitution.py | 球体を生成し、guiスライダでパラメータを動的に変更する | |
robotcontrol.py | 移動ロボットhuskyを生成し、速度制御する | 後日gif画像追加予定 |
rollPitchYaw.py | guiスライダーでオブジェクトの位置(x,y,z)と姿勢(r,p,y)を動的に変更する | |
rotationalFriction.py | 回転するボックスの上に、球体を生成する | |
satCollision.py | sat(衝突検出アルゴリズム)を有効化した状態でオブジェクトを生成する | |
saveRestoreState.py | 実行したシミュレーションデータをログファイルに保存したのちに、そのログファイルを読み込みシミュレーションを再現する | |
saveWorld.py | 現在のシミュレーションの状態を保存する |
SHARED_MEMORY モードで起動するため、gui画面は表示されません |
sceneAabb.py | シミュレーション内のすべてのAABB(軸平行境界ボックス)を計算し、最小値と最大値をターミナルに表示する | 後日、gif動画追加予定 |
segmask_linkindex.py | "1"キーを入力すると、セグメントされたピクセルをターミナル上に表示する "s"キーをクリックすると、セグメンテーションマスクのオプションを切り替える |
後日、gif画像追加予定 私の環境では、"1"キーを入力すると、 ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all() と表示され終了してしまいました |
shiftCenterOfMass.py | 質量の位置を中心から移動したボックスを生成する | |
signedDistanceField.py | 凹状のボックス内に、アヒルと球体を生成する | |
sleeping.py | 25台のロボットを生成し、各ステップごとにロボットがスリープ状態にならないように状態を更新する | |
snake.py | 蛇型ロボットを生成し、キーボードの左右キーで制御する | |
soccerball.py | 大きさの異なる球体を8個生成する | |
spherical_joint_limit.py | ジョイントのあるオブジェクトを生成し、guiスライダーで重力方向を変更する | |
switchConstraintSolver.py | 物理エンジンの制約ソルバーとしてLCP (Linear Complementarity Problem) のDantzigアルゴリズムを設定し、ボックスを生成する | (以降、qiitaへひと月にアップロードできる画像の上限が100MBである関係で、4月以降に追加します) |
test_inertia.py | 剛体のボックスと、ソフトボディのウサギを生成する | |
test.py | r2d2の位置と姿勢をターミナル上に表示し、5秒経過するとシミュレーションが終了する | |
testPlugin.py | テスト用のプラグインをロードする | |
testrender_egl.py | EGLレンダリングを使用し、リアルタイムでレンダリングしている画像をmatplotlibで描画する | |
testrender_np.py | リアルタイムでレンダリングしている画像をmatplotlibで描画する | |
testrender.py | リアルタイムでレンダリングしている画像をmatplotlibで描画する | |
transparent.py | guiスライダーで球体のオブジェクトの色と透明度を変更する | |
urdfEditor.py | 読み込んだurdfファイルを編集し、編集した後のurdfファイルからロボットを生成する | |
userData.py | データの追加/削除、データ同期などのデータの操作を行う | guiモードで起動しないのでgui画面は表示されません |
vhacd.py | オブジェクトに凸分解(V-HACD, Volumetric Hierarchical Approximate Convex Decomposition)を実施し、その結果をduck_vhacd.obj に保存する |
DIRECT モードで起動するので、gui画面は表示されません |
video_sync_mp4.py | シミュレーションをmp4形式で出力する | |
vr_kitchen_setup_vrSyncPython.py | VRコントローラのセンサ値をもとに、シミュレーションの制御を行う | 実機のハンドコントローラが必要ですが、私が所持していないため実行できていません(以下、vrとつくコードはすべて同様) |
vr_kuka_control.py | VR コントローラーを使用して、ロボットアームとグリッパーを制御する | |
vr_kuka_pr2_move.py | VRコントローラを使用して、グリッパーを制御する | |
vr_kuka_setup_vrSyncPlugin.py | VR コントローラーによるロボット操作シミュレーションを設定する | |
vr_kuka_setup_vrSyncPython.py | VRコントローラーを使用して、ロボットアームを操作する | |
vr_kuka_setup.py | ロボットアームを使用するための物理シミュレーションの設定を行う | |
vr_racecar_differential.py | 移動ロボットを制御する | |
vrEvent.py | VRコントローラーを使って線を描画する | |
vrhand_vive_tracker.py | VRグローブを使用してロボットハンドを制御する | |
vrhand.py | VRグローブを使用してロボットハンドを制御する | |
vrminitaur.py | VRコントローラーを使用してロボットを追跡する | |
vrtracker.py | VRコントローラーを使用して3D空間に線を描画する | |
widows.py | テーブルとロボットアームを生成し、追従するカメラで画像を撮影する |
さいごに
pybulletはお手軽に使えますが、情報が少ない印象があったのでこの機会にまとめてみました。
みなさんのお役に立てれば幸いです。
余談
今回書いた記事で1か月の画像の上限が100MBであること初めて知りました。もうちょっと増やして欲しいと思ったりして、、、笑
-
デフォルトのコードでは、最初の一度だけしか接触情報がターミナルに表示されないようになっています。しかし、最初の時点ではオブジェクトは宙に浮いた状態なので、ターミナル上に
()
のように空のタプルが返されてしまいます(どこにも接触していないため)。そのため、リアルタイムで床との接触情報を表示したい場合は、50行目~52行目の内容を53行目のwhileループ内に入れる必要があります。 ↩ ↩2 -
コード内16行目の
heightfieldSource
を「useProgrammatic
useTerrainFromPNG
useDeepLocoCSV
」 のいずれかに設定することで対応するモードで地形を生成できます(デフォルトでは、useProgrammatic
に設定されています)。 ↩ -
出力されたjsonファイルは
about://tracing
で可視化できます。 ↩ -
1と同様の理由で、ターミナル上に
()
のように空のタプルが返されてしまうため、リアルタイムで床との接触情報を表示したい場合は、38行目~40行目の内容を41行目のwhileループ内に入れる必要があります。 ↩