LoginSignup
27
26

Pythonで物理シミュレーションをはじめよう ~Pybullet入門~

Last updated at Posted at 2023-05-18

はじめに

my_simulation-2.gif

「Pythonで、ちゃんとした物理エンジンを動かしたい!」 という願いを叶えてくれるのがPybulletです。

少し使うのが難しいですが
特徴として

  • オープンソースである
  • ロボットのシミュレーションも行える (URDFなども読み込める)
  • 深度画像、セグメンテーション画像なども取得可能、raytestなども利用可能
  • 強化学習用の環境が一部提供されている

などが挙げられ、物理シミュレーション、ロボティクス、AIなど様々な分野で利用できます。
(実際に研究者も使っているツールです)

公式サイト
クイックスタートガイド
Git Hub

今回の実行環境について

Google Colaboratoryで実行しています。

ランタイムはGPUの方がいいですが、CPUでも動きます。
(CPUだと最初のpipインストールが10分くらいかかる)

ローカルのノートPCなどで実行しようとするとかなり重たいですが、UIで動かせるという利点があります。

インストール、インポート

Colabでやっているのでコマンドの前に「!」がついていますが環境に応じて変えてください

インストール

!pip install pybullet

インポート

import pybullet

gitのクローン
強化学習用の環境やロボットのモデル(URDFファイルなど)が読み込める。
(URDF、SDF、Objなどの形式でR2D2, Kukaのロボットアーム, レースカーなど色々なものが用意されている)

!git clone https://github.com/bulletphysics/bullet3.git

色々な設定で使うのでこちらもインポート

import pybullet_data

物理エンジンへの接続

今回はColabでやっているので

physicsClient = pybullet.connect(pybullet.DIRECT) 

もしローカルで実行する場合は

physicsClient = pybullet.connect(pybullet.GUI) 

環境の設定

基本設定

pybullet.setAdditionalSearchPath(pybullet_data.getDataPath())

重力を設定する

pybullet.setgravity(gravx,gravy,gravz)

gravx: x軸方向の重力
gravy: y軸方向の重力
gravz: z軸方向の重力
(全てfloat)

基本的には(地球上において)

pybullet.setgravity(0,0,-9.8)

物体のロード

URDF(Universal Robot Description File)のファイルを読み込める変形しやすい物体(布など)も読み込める
URDFはROSなどで用いられる

object=pybullet.loadURDF('~~~.urdf')

loadSDF:SDFファイルを読み込める
loadMJCF:MuJoCo MJCFのxmlを読み込める

VTK や OBJ 形式の変形しやすい物体(布など)を読み込める

object=pybullet.loadSoftBody('.obj')

カメラ画像の受け取り

RGB、Depth、セグメンテーション画像が受け取れます。AIの学習(特に強化学習)をする際に非常に便利な機能です。

width, height, rgbPixels, depthPixels, segmentationMaskBuffer = pybullet.getCameraImage(width, height, ...)

RGB画像(rgbPixels)
スクリーンショット 2021-04-05 13.36.22.png

深度(Depth)カメラ映像(depthPixels)
スクリーンショット 2021-04-05 13.37.59.png

セグメンテーションマスク(segmentationMaskBuffer)
スクリーンショット 2021-04-05 13.38.40.png

カメラ設定

getCameraImageの引数

pybullet.getCameraImage(width, height, viewMatrix , projectionMatrix, lightDirection, lightColor, lightDistance, shadow, lightAmbientCoeff, lightDiffuseCoeff, lightSpecularCoeff, renderer)

主なパラメーター 意味
width 画像の横幅
height 画像の高さ
viewMatrix カメラの位置、方向など(下記参照)
projectionMatrix カメラの撮影設定(下記参照)
lightDirection ライトの方向ベクトル lightDirection= (x,y,z)
lightColor ライトの色 lightColor=(R,G,B)
lightDistance ライトの距離
shadow 影をつけるかどうか: 1→影をつける 0→影をつけない

カメラの位置、方向など

viewMatrix = pybullet.computeViewMatrix(cameraEyePosition=[0, 0, 2],cameraTargetPosition=[0, 0, 0],cameraUpVector=[0, 1, 0])
主なパラメーター 意味
cameraEyePosition カメラの位置
cameraTargetPosition カメラが写す中心座標
cameraUpVector カメラの上面の法線ベクトル※

※カメラが中心座標をどのくらい見下ろすor見上げるのかを決める

カメラの撮影設定

projectionMatrix = pybullet.computeProjectionMatrixFOV(fov=45.0,aspect=1.0,nearVal=0.1,farVal=3.1)
主なパラメーター 意味
fov カメラが写す範囲の広さ
aspect アスペクト(画像の縦横比)
nearVal カメラが写す最小の距離
farVal カメラが写す最大の距離

シミュレーション結果の表示・保存

下のコードを実行すると、3次元直交座標(0,0,3)から、重力加速度9.8でヒューマノイドが自由落下するシミュレーション結果をGIFファイルで保存できます。

from PIL import Image

pybullet.resetSimulation()
pybullet.setAdditionalSearchPath(pybullet_data.getDataPath())
pybullet.setGravity(0,0,-9.8)
timestep = 1. / 240.
pybullet.setTimeStep(timestep)
floor = pybullet.loadURDF("plane.urdf")

startposition = [0,0,3]  # x,y,z
startorient = pybullet.getQuaternionFromEuler([0,0,3.14])  
Humanoid = pybullet.loadURDF("./bullet3/data/humanoid/nao.urdf",startposition, startorient) 
 # 記事冒頭のボールを落下させるシミュレーションでは "./bullet3/data/sphere2.urdf"を指定

frame = []
for t in range (400):
    pybullet.stepSimulation()
    if t % 8 == 0:
        width, height, rgbImg, depthImg, segImg = pybullet.getCameraImage(360,240)
        frame.append(rgbImg)

images =[]
for im in frame:
  img = Image.fromarray(im)
  images.append(img)
images[0].save('my_simulation.gif',save_all=True, append_images=images[:], optimize=False, duration=40, loop=0)

実行結果

my_simulation.gif

ヒューマノイドの設定(色、コリジョンなど)はURDFを編集することで変更できます。

最後に

今回は、Pybulletの基本的な使い方を紹介しました。

自分もまだわからない部分が多いので、たくさん使って勉強していきたいと思います。

間違いなどがあれば遠慮なくコメントで指摘をお願いします。

以下の関連記事では実際にPybulletでロボットを動かす方法を解説しています
Racecar_moving1.gif

27
26
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
27
26