Pybullet公式gitリポジトリのサンプルコードを解説するシリーズです(一覧はこちら)。
今回は、humanoid_manual_control.pyを解説します。(コードのリンクはこちら)
本コードを実行すると、ヒューマノイドロボットが生成され、各関節をスライダーにより操作することが可能になります。
コメントをつけたサンプルコード
サンプルコードにコメントをつけたものが以下になります(もともとあった不要と思われるコメント等については削除しています)
import pybullet as p
import time
import pybullet_data
# GUIモードで物理サーバーに接続
p.connect(p.GUI)
# PyBullet付属データを検索パスに追加(humanoid.xml読込み用)
p.setAdditionalSearchPath(pybullet_data.getDataPath())
# MJCF 形式の humanoid モデルを読み込み(戻り値は複数オブジェクト)
obUids = p.loadMJCF("mjcf/humanoid.xml")
humanoid = obUids[1] # 2番目が人体モデル
# 重力用スライダー:−10〜+10 の範囲で初期値 −10
gravId = p.addUserDebugParameter("gravity", -10, 10, -10)
jointIds = []
paramIds = []
# 制約解決精度を高めるためソルバーイテレーション回数を 10 に設定
p.setPhysicsEngineParameter(numSolverIterations=10)
# ベースリンクのダンピングをゼロ化
p.changeDynamics(humanoid, -1, linearDamping=0, angularDamping=0)
# 全関節をループし、デュンピング除去&可動関節にスライダー生成
for j in range(p.getNumJoints(humanoid)):
p.changeDynamics(humanoid, j, linearDamping=0, angularDamping=0)
info = p.getJointInfo(humanoid, j)
jointName = info[1].decode("utf-8")
jointType = info[2]
if jointType in (p.JOINT_PRISMATIC, p.JOINT_REVOLUTE):
jointIds.append(j)
paramIds.append(p.addUserDebugParameter(jointName, -4, 4, 0))
# リアルタイムモード開始:ループで step 不要に
p.setRealTimeSimulation(1)
while True:
# スライダーから重力値読み込み
g = p.readUserDebugParameter(gravId)
p.setGravity(0, 0, g)
# 各関節のターゲット角度を読み込み位置制御
for jid, pid in zip(jointIds, paramIds):
target = p.readUserDebugParameter(pid)
p.setJointMotorControl2(
humanoid, jid,
p.POSITION_CONTROL,
targetPos=target,
force=5 * 240.0 # 高トルクで即時追従
)
# CPU負荷低減のためスリープ
time.sleep(0.01)