文章目录
- 安装
- 介绍
-
- [🧩 一、PyBullet 简介](#🧩 一、PyBullet 简介)
- [🚀 二、入门阶段(基础使用)](#🚀 二、入门阶段(基础使用))
-
- [1. 安装](#1. 安装)
- [2. 第一个仿真:加载 URDF 模型](#2. 第一个仿真:加载 URDF 模型)
- [🧠 三、进阶阶段(理解系统组成)](#🧠 三、进阶阶段(理解系统组成))
-
- [1. 世界构建](#1. 世界构建)
- [2. 机器人控制](#2. 机器人控制)
- [3. 传感器仿真](#3. 传感器仿真)
- [🧩 四、实战项目方向(推荐)](#🧩 四、实战项目方向(推荐))
- [⚙️ 五、深入阶段(原理与扩展)](#⚙️ 五、深入阶段(原理与扩展))
-
- [1. 物理引擎底层](#1. 物理引擎底层)
- [2. 与其他框架结合](#2. 与其他框架结合)
- [📚 六、学习资源推荐](#📚 六、学习资源推荐)
- [💡 七、学习建议](#💡 七、学习建议)
- [PyBullet Quickstart Guide](#PyBullet Quickstart Guide)
- [1. Introduction](#1. Introduction)
-
-
- [Hello PyBullet World](#Hello PyBullet World)
-
- [🧭 PyBullet 基础核心 API 详解(中英对照整理版)](#🧭 PyBullet 基础核心 API 详解(中英对照整理版))
-
- [🧩 1. connect / disconnect / bullet\_client](#🧩 1. connect / disconnect / bullet_client)
-
- [✅ 1.1 connect ------ 连接到物理仿真服务器](#✅ 1.1 connect —— 连接到物理仿真服务器)
- [🔹 内置的服务器类型](#🔹 内置的服务器类型)
- [🔹 语法](#🔹 语法)
- [🔹 可选参数(部分模式)](#🔹 可选参数(部分模式))
- [🔹 连接方式汇总](#🔹 连接方式汇总)
- [✅ 1.2 getConnectionInfo / isConnected / setTimeOut](#✅ 1.2 getConnectionInfo / isConnected / setTimeOut)
- [✅ 1.3 disconnect ------ 断开连接](#✅ 1.3 disconnect —— 断开连接)
- [✅ 1.4 bullet\_client ------ 多仿真并行管理](#✅ 1.4 bullet_client —— 多仿真并行管理)
- [🌍 2. setGravity](#🌍 2. setGravity)
- [🤖 3. 加载机器人模型:loadURDF / loadSDF / loadMJCF](#🤖 3. 加载机器人模型:loadURDF / loadSDF / loadMJCF)
-
- [✅ 3.1 loadURDF](#✅ 3.1 loadURDF)
-
- [⚠️ 注意事项](#⚠️ 注意事项)
- [🔹 常用参数](#🔹 常用参数)
- [🔹 常用 flags](#🔹 常用 flags)
- [✅ 3.2 loadSDF / loadMJCF](#✅ 3.2 loadSDF / loadMJCF)
- [💾 4. 状态保存与恢复](#💾 4. 状态保存与恢复)
- [🧱 5. 创建几何形状(低级 API)](#🧱 5. 创建几何形状(低级 API))
-
- [✅ 5.1 createCollisionShape ------ 创建碰撞体](#✅ 5.1 createCollisionShape —— 创建碰撞体)
- [✅ 5.2 createVisualShape ------ 创建视觉形状](#✅ 5.2 createVisualShape —— 创建视觉形状)
- [✅ 5.3 createCollisionShapeArray / removeCollisionShape](#✅ 5.3 createCollisionShapeArray / removeCollisionShape)
- [🧱 PyBullet 几何形状与多体系统、仿真步骤、姿态转换(中英对照详解)](#🧱 PyBullet 几何形状与多体系统、仿真步骤、姿态转换(中英对照详解))
-
- [🧩 1️⃣ createVisualShape ------ 创建视觉形状(Visual Shape)](#🧩 1️⃣ createVisualShape —— 创建视觉形状(Visual Shape))
-
- [🔹 语法](#🔹 语法)
- [🔹 参数说明](#🔹 参数说明)
- [💡 示例](#💡 示例)
- [🧩 2️⃣ createVisualShapeArray ------ 批量创建视觉形状](#🧩 2️⃣ createVisualShapeArray —— 批量创建视觉形状)
- [🧩 3️⃣ createMultiBody ------ 创建多体系统(Rigid body + Links)](#🧩 3️⃣ createMultiBody —— 创建多体系统(Rigid body + Links))
-
- [🔹 用法示例](#🔹 用法示例)
- [🔹 参数说明(基础部分)](#🔹 参数说明(基础部分))
- [🔹 多连杆(links)扩展部分](#🔹 多连杆(links)扩展部分)
- [🔹 支持的关节类型](#🔹 支持的关节类型)
- [🔹 其他参数](#🔹 其他参数)
- [🧩 4️⃣ getMeshData ------ 获取网格信息(实验性)](#🧩 4️⃣ getMeshData —— 获取网格信息(实验性))
- [🧩 5️⃣ stepSimulation ------ 单步仿真推进](#🧩 5️⃣ stepSimulation —— 单步仿真推进)
- [🧩 6️⃣ performCollisionDetection ------ 仅执行碰撞检测阶段](#🧩 6️⃣ performCollisionDetection —— 仅执行碰撞检测阶段)
- [🧩 7️⃣ setRealTimeSimulation ------ 开启/关闭实时仿真](#🧩 7️⃣ setRealTimeSimulation —— 开启/关闭实时仿真)
- [🧩 8️⃣ getBasePositionAndOrientation ------ 获取基座姿态](#🧩 8️⃣ getBasePositionAndOrientation —— 获取基座姿态)
- [🧩 9️⃣ resetBasePositionAndOrientation ------ 重置基座姿态](#🧩 9️⃣ resetBasePositionAndOrientation —— 重置基座姿态)
- [🧩 🔄 姿态与坐标变换工具函数](#🧩 🔄 姿态与坐标变换工具函数)
- [🧭 PyBullet 仿真流程图(从零开始)](#🧭 PyBullet 仿真流程图(从零开始))
- [💻 完整 Python 示例代码](#💻 完整 Python 示例代码)
- [📘 总结要点](#📘 总结要点)
安装
Pybullet 安装过程(windows)
- 安装C++编译工具
pybullet 需要C++编译套件,直接装之前检查下,要不会报缺少某版本MVSC的error,最好的方式是直接下载visual studio,直接按默认选的组件来装,装的磁盘位置可以自定义。

- 安装Pybullet
这里使用清华源安装
bash
pip install pybullet -i https://pypi.tuna.tsinghua.edu.cn/simple
3 安装后再Lib/site-packages目录下出现下面的目录

介绍
🧩 一、PyBullet 简介
PyBullet 是 Bullet Physics 引擎的 Python 接口,具有以下特点:
- 开源、跨平台(Windows/Linux/macOS)
- 易用的 Python API
- 支持刚体、关节、机器人、布料、软体仿真
- 支持真实渲染、GUI 与无界面模式
- 适用于强化学习(RL)环境,如 OpenAI Gym、MetaWorld、Roboschool 等
🚀 二、入门阶段(基础使用)
1. 安装
bash
pip install pybullet
2. 第一个仿真:加载 URDF 模型
python
import pybullet as p
import pybullet_data
import time
# 启动物理仿真 GUI
p.connect(p.GUI)
# 加载基础环境
p.setAdditionalSearchPath(pybullet_data.getDataPath())
p.loadURDF("plane.urdf")
# 加载一个机器人(这里是 KUKA 机械臂)
robot = p.loadURDF("kuka_iiwa/model.urdf", [0, 0, 0], useFixedBase=True)
# 模拟重力
p.setGravity(0, 0, -9.8)
# 运行仿真
for _ in range(10000):
p.stepSimulation()
time.sleep(1./240.)
p.disconnect()
👉 重点理解
URDF
是机器人模型文件(XML 格式)p.stepSimulation()
是核心循环- 可以通过 GUI 界面实时查看仿真效果
🧠 三、进阶阶段(理解系统组成)
1. 世界构建
- 创建环境(地面、障碍物)
- 加载多个模型(URDF、MJCF、OBJ)
- 设置物理参数(重力、摩擦、约束等)
2. 机器人控制
通过 关节控制模式 操作机器人:
python
p.setJointMotorControl2(
bodyIndex=robot,
jointIndex=2,
controlMode=p.POSITION_CONTROL,
targetPosition=1.0,
force=500
)
控制模式包括:
POSITION_CONTROL
VELOCITY_CONTROL
TORQUE_CONTROL
3. 传感器仿真
- 获取相机图像 (
getCameraImage
) - 深度图与分割图
- 获取接触力 (
getContactPoints
) - IMU、力传感器、激光雷达等可模拟
🧩 四、实战项目方向(推荐)
应用方向 | 示例项目 | 说明 |
---|---|---|
🤖 机器人仿真 | UR5机械臂、Spot机器人 | 学会运动学、路径规划 |
🚗 自动驾驶 | 加载车辆模型 + 传感器模拟 | 实现LIDAR + camera fusion |
🧬 强化学习 | PyBullet Gym Envs | 学习PPO、SAC、TD3算法 |
🧶 软体仿真 | 旗帜、布料、柔性手 | 使用 loadSoftBody() |
例如,强化学习中加载 Ant 环境:
python
import pybullet_envs
import gym
env = gym.make('AntBulletEnv-v0')
obs = env.reset()
for _ in range(1000):
action = env.action_space.sample()
obs, reward, done, info = env.step(action)
env.render()
⚙️ 五、深入阶段(原理与扩展)
1. 物理引擎底层
- 碰撞检测(Collision Detection)
- 约束求解器(Constraint Solver)
- 积分与时间步长控制
- 摩擦、弹性、阻尼建模
可参考论文:
- Coumans, E., & Bai, Y. (2016). PyBullet, a Python module for physics simulation for games, robotics and machine learning.
2. 与其他框架结合
框架 | 用途 |
---|---|
ROS | 机器人系统通信 |
OpenAI Gym / RLlib | 强化学习 |
Open3D / PyVista | 可视化 |
TensorFlow / PyTorch | 控制策略学习 |
📚 六、学习资源推荐
类型 | 资源 |
---|---|
官方文档 | https://pybullet.org/wordpress/ |
GitHub | https://github.com/bulletphysics/bullet3 |
教程仓库 | https://github.com/benelot/pybullet-gym |
视频课程 | 搜 "PyBullet Robotics Tutorial" |
中文参考 | 搜索 "PyBullet 教程 / 机器人仿真" |
💡 七、学习建议
- 先跑通 GUI 示例 → 熟悉 API
- 学 URDF/MJCF 文件结构 → 会修改机器人模型
- 做一个控制项目 → 例如机械臂抓取
- 结合 RL 环境 → 学会调用 Gym 接口
- 阅读源码与 Bullet 论文 → 深入动力学原理
PyBullet Quickstart Guide
1. Introduction
PyBullet 是一个快速且易于使用的 Python 模块,用于机器人仿真和机器学习,特别注重 仿真到现实(sim-to-real)迁移 。
使用 PyBullet,你可以从 URDF、SDF、MJCF 以及其他文件格式加载多关节机器人模型(articulated bodies)。
PyBullet 提供以下功能:
- 正向动力学仿真(forward dynamics simulation)
- 逆动力学计算(inverse dynamics computation)
- 正/逆运动学求解(forward and inverse kinematics)
- 碰撞检测与射线检测(collision detection and ray intersection queries)
Bullet Physics SDK 中包含许多使用 PyBullet 的机器人示例,例如:
- 模拟的 Minitaur 四足机器人
- 使用 TensorFlow 推理(inference) 驱动的人形机器人(humanoids)
- KUKA 机械臂抓取物体 的仿真场景
PyBullet 使用统一的 LCP(线性互补问题)约束求解器(constraint solver) 处理:
- 降维坐标多体系统(reduced coordinate multibodies)
- 刚体(rigid bodies)
- 可变形体(deformables)
这一求解器与本论文中的 Articulated Islands Algorithm(关节岛算法) 类似,
并采用 Articulated Body Algorithm(关节体算法) 实现线性时间的正向动力学计算与求解矩阵 A 的构建。
除了物理仿真功能之外,PyBullet 还提供了渲染接口,包括:
- CPU 渲染器(TinyRenderer)
- OpenGL 3.x 渲染与可视化
- 对虚拟现实设备的支持(如 HTC Vive 和 Oculus Rift)
PyBullet 还具有多种几何查询功能:
- 碰撞检测(closest points、overlapping pairs)
- 射线检测(ray intersection test)
- 调试渲染功能(debug lines 与 debug text)
PyBullet 内置 跨平台的客户端-服务器通信支持,包括:
- 共享内存(shared memory)
- UDP 与 TCP 网络协议
这意味着你可以在 Linux 上运行 PyBullet,同时连接到 Windows 上的 VR 服务器。
PyBullet 封装了全新的 Bullet C API ,该 API 被设计为独立于底层物理引擎与渲染引擎,
因此可以轻松迁移到更新版本的 Bullet,或替换为其他物理/渲染引擎。
默认情况下,PyBullet 使用 基于 CPU 的 Bullet 2.x API ,
未来将开放基于 OpenCL GPU 的 Bullet 3.x 支持。
同时还提供与 PyBullet 类似的 C++ API ,称为 b3RobotSimulatorClientAPI
。
PyBullet 可以很方便地与 TensorFlow 和 OpenAI Gym 一起使用。
目前,来自以下机构的研究人员都在使用 PyBullet:
- Google Brain
- X(Google X)
- Stanford AI Lab(斯坦福人工智能实验室)
- OpenAI
- INRIA(法国国家信息与自动化研究所)
以及许多其他实验室。
Hello PyBullet World
bash
import pybullet as p
import time
import pybullet_data
physicsClient = p.connect(p.GUI)#or p.DIRECT for non-graphical version
p.setAdditionalSearchPath(pybullet_data.getDataPath()) #optionally
p.setGravity(0,0,-10)
planeId = p.loadURDF("plane.urdf")
startPos = [0,0,1]
startOrientation = p.getQuaternionFromEuler([0,0,0])
boxId = p.loadURDF("r2d2.urdf",startPos, startOrientation)
#set the center of mass frame (loadURDF sets base link frame)
startPos/Ornp.resetBasePositionAndOrientation(boxId, startPos,
startOrientation)
for i in range (10000):
p.stepSimulation()
time.sleep(1./240.)
cubePos, cubeOrn = p.getBasePositionAndOrientation(boxId)
print(cubePos,cubeOrn)
p.disconnect()
好的 👍 这段是 PyBullet 官方文档中最核心的部分之一 ,介绍了连接、断开、加载模型以及创建物体的 API。
下面我帮你把这部分系统翻译 + 梳理成中文学习笔记结构化版,方便你学习或查阅(已去掉冗余和重复信息,保持技术准确性)。
🧭 PyBullet 基础核心 API 详解(中英对照整理版)
🧩 1. connect / disconnect / bullet_client
✅ 1.1 connect ------ 连接到物理仿真服务器
在使用 PyBullet 前,第一步必须"连接"到物理仿真 。
PyBullet 基于 客户端-服务器(Client--Server)架构 设计:
- Client(客户端) 负责发送命令
- Server(服务器) 执行物理仿真并返回状态
🔹 内置的服务器类型
PyBullet 自带两种主要服务器:
模式 | 功能 |
---|---|
p.DIRECT |
无图形界面,直接执行仿真(适合云端或无 GPU 环境) |
p.GUI |
带 OpenGL 图形界面的交互式仿真窗口 |
注意:DIRECT 模式下无法访问 OpenGL/VR 硬件功能,但可以用软件渲染 (
getCameraImage
) 获取图像。
🔹 语法
python
import pybullet as p
cid = p.connect(p.GUI) # 连接 GUI 模式
# cid = p.connect(p.DIRECT) # 连接无界面模式
# cid = p.connect(p.UDP, "localhost", 1234) # 远程连接
返回值:
physicsClientId
(非负整数) → 成功连接-1
→ 连接失败
每次连接返回一个 ID,多连接时需在其他 API 调用中指定
physicsClientId
。
🔹 可选参数(部分模式)
参数 | 说明 |
---|---|
connection_mode |
连接模式(DIRECT, GUI, SHARED_MEMORY, UDP, TCP, GUI_SERVER 等) |
options |
传入 GUI 选项(如背景颜色、窗口大小等) |
hostName |
远程服务器地址(如 "127.0.0.1") |
port |
网络端口(UDP 默认 1234,TCP 默认 6667) |
示例:
python
p.connect(p.GUI, options="--background_color_red=0.2 --background_color_blue=0.3")
p.connect(p.UDP, "192.168.0.1", 1234)
🔹 连接方式汇总
模式 | 描述 |
---|---|
DIRECT |
直接与仿真引擎通信,无图形界面 |
GUI |
创建带有 OpenGL 渲染窗口的仿真界面 |
SHARED_MEMORY |
连接到本机其他进程中的物理服务器(共享内存) |
UDP / TCP |
连接到远程物理服务器 |
GUI_SERVER |
类似 GUI,但允许外部共享内存连接 |
SHARED_MEMORY_SERVER |
类似 DIRECT,但允许共享内存客户端连接 |
SHARED_MEMORY_GUI |
与外部图形服务器连接(如 ExampleBrowser) |
✅ 1.2 getConnectionInfo / isConnected / setTimeOut
函数 | 功能 |
---|---|
getConnectionInfo(clientId) |
返回连接信息 [isConnected, connectionMethod] |
isConnected(clientId) |
返回是否连接成功(True/False) |
setTimeOut(seconds) |
设置命令超时时间,超时未响应将自动断开连接 |
✅ 1.3 disconnect ------ 断开连接
python
p.disconnect(physicsClientId=cid)
- 如果是
DIRECT
或GUI
,会关闭仿真引擎。 - 如果是远程物理服务器,则服务器继续运行。
✅ 1.4 bullet_client ------ 多仿真并行管理
PyBullet 支持同时运行多个独立仿真环境。
使用 pybullet_utils.bullet_client
可以方便地管理多个连接。
python
from pybullet_utils import bullet_client
c1 = bullet_client.BulletClient(connection_mode=p.DIRECT)
c2 = bullet_client.BulletClient(connection_mode=p.GUI)
每个 BulletClient
实例都自动管理自己的 physicsClientId
,
API 与 pybullet 完全一致。
例如:强化学习环境(如 pybullet_envs)通过
bullet_client
管理多个并行仿真实例。
🌍 2. setGravity
默认情况下,PyBullet 中无重力。
使用以下命令启用:
python
p.setGravity(0, 0, -9.8)
参数:
gravX, gravY, gravZ
:分别为 X/Y/Z 方向的重力分量physicsClientId
(可选):多服务器时指定哪个仿真环境
🤖 3. 加载机器人模型:loadURDF / loadSDF / loadMJCF
✅ 3.1 loadURDF
用于加载 URDF 格式的机器人/场景模型。
python
robot_id = p.loadURDF("kuka_iiwa/model.urdf", [0, 0, 0], useFixedBase=True)
URDF(Universal Robot Description Format)是 ROS 中常用的机器人描述文件。
⚠️ 注意事项
- URDF 中的关节通常默认启用电机(motor),阻止自由运动。
→ 使用setJointMotorControl2
修改控制模式。 - PyBullet 会缓存文件以加快加载,可通过
p.setPhysicsEngineParameter(enableFileCaching=0)
关闭。
🔹 常用参数
参数 | 说明 |
---|---|
fileName |
URDF 文件路径 |
basePosition |
初始位置 [x, y, z] |
baseOrientation |
初始姿态四元数 [x, y, z, w] |
useFixedBase |
是否固定底座 |
useMaximalCoordinates |
是否使用最大坐标法(性能优化) |
globalScaling |
模型缩放系数 |
flags |
控制加载行为的标志位(见下表) |
🔹 常用 flags
flag | 功能 |
---|---|
URDF_USE_SELF_COLLISION |
启用自碰撞检测 |
URDF_MERGE_FIXED_LINKS |
合并固定链接(提升性能) |
URDF_USE_INERTIA_FROM_FILE |
使用文件中定义的惯性张量 |
URDF_ENABLE_SLEEPING |
启用休眠(未运动时暂停计算) |
URDF_USE_MATERIAL_COLORS_FROM_MTL |
从 .mtl 文件读取材质颜色 |
URDF_ENABLE_CACHED_GRAPHICS_SHAPES |
缓存图形形状,加快加载速度 |
返回:bodyUniqueId(模型唯一 ID,整数)
✅ 3.2 loadSDF / loadMJCF
python
ids = p.loadSDF("husky/husky.sdf")
格式 | 说明 |
---|---|
.sdf |
支持多物体模型(Gazebo 格式) |
.mjcf |
MuJoCo 格式(常用于 OpenAI Gym) |
返回:多个对象的 ID 列表 [id1, id2, ...]
💾 4. 状态保存与恢复
函数 | 功能 |
---|---|
saveState() |
保存当前仿真状态到内存 |
saveBullet(filename) |
保存状态到 .bullet 文件 |
restoreState(fileName/stateId) |
从保存状态恢复(包括接触点) |
removeState(stateId) |
删除保存的状态 |
saveWorld(filename) |
保存当前世界为 Python 文件(可重新加载) |
⚠️ 注意:恢复状态前必须重新加载相同模型和约束结构。
🧱 5. 创建几何形状(低级 API)
虽然加载 URDF/SDF 是最常见的方式,
但也可以使用以下函数直接创建几何形状:
✅ 5.1 createCollisionShape ------ 创建碰撞体
python
shape_id = p.createCollisionShape(
p.GEOM_BOX,
halfExtents=[0.5, 0.5, 0.5]
)
参数 | 说明 |
---|---|
shapeType |
几何类型(GEOM_SPHERE, BOX, CYLINDER, MESH 等) |
radius , halfExtents , height |
几何参数 |
fileName |
网格文件路径(.obj) |
meshScale |
网格缩放 |
planeNormal |
平面法向量 |
flags |
特殊选项,如 GEOM_FORCE_CONCAVE_TRIMESH (用于静态凹面) |
返回:collisionShapeId
✅ 5.2 createVisualShape ------ 创建视觉形状
python
vis_id = p.createVisualShape(
p.GEOM_BOX,
halfExtents=[0.5, 0.5, 0.5],
rgbaColor=[0.2, 0.5, 0.8, 1.0]
)
可设置颜色、纹理、镜面反射等属性。
用于视觉显示,不参与物理计算。
✅ 5.3 createCollisionShapeArray / removeCollisionShape
createCollisionShapeArray
:批量创建多个形状(提高效率)removeCollisionShape(id)
:移除碰撞形状
🧱 PyBullet 几何形状与多体系统、仿真步骤、姿态转换(中英对照详解)
🧩 1️⃣ createVisualShape ------ 创建视觉形状(Visual Shape)
与 createCollisionShape
类似,但只影响 渲染外观,不参与物理计算。
🔹 语法
python
shape_id = p.createVisualShape(
shapeType=p.GEOM_BOX,
halfExtents=[1,1,1],
rgbaColor=[0.5,0.2,0.8,1]
)
🔹 参数说明
参数名 | 类型 | 适用 | 默认值 | 说明 |
---|---|---|---|---|
shapeType | int | 必需 | --- | 形状类型(GEOM_SPHERE , GEOM_BOX , GEOM_CAPSULE , GEOM_CYLINDER , GEOM_PLANE , GEOM_MESH ) |
radius | float | 球体/胶囊/圆柱 | 0.5 | 半径 |
halfExtents | vec3 | 盒体 | [1,1,1] | 长宽高的一半 |
length | float | 胶囊/圆柱 | 1 | 长度或高度 |
fileName | str | 网格 | --- | Wavefront .obj 文件路径 |
meshScale | vec3 | 网格 | [1,1,1] | 缩放比例 |
planeNormal | vec3 | 平面 | [0,0,1] | 平面法线 |
flags | int | --- | 0 | 备用(暂未使用) |
rgbaColor | vec4 | 所有 | --- | RGBA 颜色(0~1) |
specularColor | vec3 | 所有 | --- | 镜面反射颜色(RGB 0~1) |
visualFramePosition | vec3 | 所有 | [0,0,0] | 可视形状相对 link 的平移偏移 |
visualFrameOrientation | vec4 | 所有 | [0,0,0,1] | 可视形状相对 link 的旋转(四元数) |
vertices / indices / uvs / normals | list | 网格 | --- | 若不使用 .obj 文件,可直接传入顶点数据 |
physicsClientId | int | 多连接时 | --- | 指定仿真客户端 |
返回值:
- 成功:视觉形状 ID(非负整数)
- 失败:-1
💡 示例
python
# 1. 立方体可视形状
cube_vis = p.createVisualShape(
shapeType=p.GEOM_BOX,
halfExtents=[1,1,1],
rgbaColor=[0.2, 0.6, 0.8, 1]
)
# 2. 球体可视形状
sphere_vis = p.createVisualShape(
shapeType=p.GEOM_SPHERE,
radius=0.5,
specularColor=[0.5,0.5,0.5]
)
🧩 2️⃣ createVisualShapeArray ------ 批量创建视觉形状
和 createVisualShape
相同,只是参数改为列表形式,适合同时创建多个对象。
参见官方示例:createVisualShapeArray.py
🧩 3️⃣ createMultiBody ------ 创建多体系统(Rigid body + Links)
虽然通常使用 loadURDF()
、loadSDF()
来加载模型,
但 createMultiBody()
可以让你手动定义物体与连杆的物理结构 ,
实现完全自定义的物理系统。
🔹 用法示例
python
cuid = p.createCollisionShape(p.GEOM_BOX, halfExtents=[1,1,1])
mass = 0 # 静态物体
body = p.createMultiBody(baseMass=mass, baseCollisionShapeIndex=cuid)
🔹 参数说明(基础部分)
参数 | 类型 | 默认 | 说明 |
---|---|---|---|
baseMass | float | 0 | 底座质量(kg) |
baseCollisionShapeIndex | int | -1 | createCollisionShape 的返回 ID |
baseVisualShapeIndex | int | -1 | createVisualShape 的返回 ID |
basePosition | vec3 | [0,0,0] | 底座世界坐标位置 |
baseOrientation | vec4 | [0,0,0,1] | 底座姿态(四元数) |
baseInertialFramePosition | vec3 | [0,0,0] | 惯性中心偏移位置 |
baseInertialFrameOrientation | vec4 | [0,0,0,1] | 惯性中心偏移方向 |
🔹 多连杆(links)扩展部分
注意:所有 list 参数的长度必须一致。
参数 | 类型 | 说明 |
---|---|---|
linkMasses |
list[float] | 每个连杆的质量 |
linkCollisionShapeIndices |
list[int] | 每个连杆的碰撞形状 ID |
linkVisualShapeIndices |
list[int] | 每个连杆的视觉形状 ID |
linkPositions |
list[vec3] | 连杆相对于父节点的局部位置 |
linkOrientations |
list[vec4] | 连杆局部姿态(四元数) |
linkInertialFramePositions |
list[vec3] | 连杆惯性坐标系位置 |
linkInertialFrameOrientations |
list[vec4] | 连杆惯性坐标系方向 |
linkParentIndices |
list[int] | 父节点索引(0 为 base) |
linkJointTypes |
list[int] | 关节类型(见下) |
linkJointAxis |
list[vec3] | 关节旋转轴方向(局部坐标) |
🔹 支持的关节类型
类型 | 含义 |
---|---|
p.JOINT_REVOLUTE |
转动关节(Revolute) |
p.JOINT_PRISMATIC |
直线关节(滑动) |
p.JOINT_SPHERICAL |
球面关节 |
p.JOINT_FIXED |
固定连接 |
🔹 其他参数
参数 | 说明 |
---|---|
useMaximalCoordinates |
是否使用最大坐标法(实验性) |
flags |
与 loadURDF 类似的控制选项(如 URDF_USE_SELF_COLLISION ) |
batchPositions |
批量创建多个多体时的基础位置列表 |
physicsClientId |
指定仿真客户端 |
返回值:
- 成功:唯一的 body ID
- 失败:-1
🧩 4️⃣ getMeshData ------ 获取网格信息(实验性)
用于获取物体的网格顶点与索引。
参数 | 类型 | 说明 |
---|---|---|
bodyUniqueId |
int | 物体 ID |
linkIndex |
int | 连杆索引 |
collisionShapeIndex |
int | 复合碰撞形状的索引 |
flags |
int | 选择网格数据类型(渲染/仿真) |
physicsClientId |
int | 多客户端选择 |
示例:
python
verts, indices = p.getMeshData(body_id, linkIndex=0)
🧩 5️⃣ stepSimulation ------ 单步仿真推进
执行一步完整的仿真更新(碰撞检测 + 约束求解 + 动力学积分)。
python
p.stepSimulation()
默认时间步:1/240s
可通过 p.setTimeStep()
修改。
返回:
-
默认无返回值
-
若启用
reportSolverAnalytics
,则返回每个「动力学岛(island)」的信息:islandId
numBodies
numIterationsUsed
remainingResidual
🧩 6️⃣ performCollisionDetection ------ 仅执行碰撞检测阶段
python
p.performCollisionDetection()
执行碰撞检测但不积分、不求解约束 。
执行后可用 p.getContactPoints()
获取接触信息。
🧩 7️⃣ setRealTimeSimulation ------ 开启/关闭实时仿真
默认情况下,仿真不会自动运行(需要手动 stepSimulation()
)。
若想让物理引擎根据系统时钟自动前进,可启用:
python
p.setRealTimeSimulation(1)
参数 | 说明 |
---|---|
enableRealTimeSimulation |
1 启用、0 禁用 |
physicsClientId |
可选 |
⚠️ 注意:
DIRECT
模式下无效。GUI
、VR
、TCP/UDP
模式下有效(服务器线程自动运行)。
🧩 8️⃣ getBasePositionAndOrientation ------ 获取基座姿态
python
pos, orn = p.getBasePositionAndOrientation(body_id)
返回:
pos
→ [x, y, z]orn
→ [x, y, z, w](四元数)
可用 p.getEulerFromQuaternion(orn)
转换为欧拉角。
🧩 9️⃣ resetBasePositionAndOrientation ------ 重置基座姿态
python
p.resetBasePositionAndOrientation(body_id, [0,0,1], [0,0,0,1])
通常用于初始化阶段,不建议在仿真中动态修改。
此操作会清零线速度和角速度。
若需设定初始速度,用 resetBaseVelocity()
。
🧩 🔄 姿态与坐标变换工具函数
PyBullet 提供若干辅助函数来处理姿态转换。
函数 | 功能 | 输入 / 输出 |
---|---|---|
getQuaternionFromEuler(euler) |
欧拉角 → 四元数 | 输入 [roll, pitch, yaw] → 输出 [x, y, z, w] |
getEulerFromQuaternion(quat) |
四元数 → 欧拉角 | 输入 [x, y, z, w] → 输出 [roll, pitch, yaw] |
getMatrixFromQuaternion(quat) |
四元数 → 3×3 旋转矩阵 | 输出 9 个浮点数的列表 |
getAxisAngleFromQuaternion(quat) |
四元数 → 旋转轴 + 角度 | 返回 (axis, angle) |
multiplyTransforms(posA, ornA, posB, ornB) |
复合两个位姿变换 | 输出合并后的 (pos, orn) |
invertTransform(pos, orn) |
求逆变换 | 返回反向的 (pos, orn) |
✅ 小结
功能类别 | 关键函数 |
---|---|
创建视觉形状 | createVisualShape , createVisualShapeArray |
创建物理系统 | createMultiBody |
仿真与碰撞 | stepSimulation , performCollisionDetection , setRealTimeSimulation |
获取/重置姿态 | getBasePositionAndOrientation , resetBasePositionAndOrientation |
姿态转换工具 | getQuaternionFromEuler , getEulerFromQuaternion , multiplyTransforms 等 |
🧭 PyBullet 仿真流程图(从零开始)
┌────────────────────────────────────────────┐
│ 1️⃣ 连接物理引擎服务器 │
│ connect(p.GUI / p.DIRECT / p.SHARED) │
└────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────┐
│ 2️⃣ 设置物理参数(可选) │
│ setGravity(), setTimeStep(), etc. │
└────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────┐
│ 3️⃣ 创建或加载物体模型 │
│ loadURDF() / createCollisionShape() │
│ + createVisualShape() + createMultiBody() │
└────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────┐
│ 4️⃣ 初始化位置与姿态(可选) │
│ resetBasePositionAndOrientation() │
│ resetBaseVelocity() │
└────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────┐
│ 5️⃣ 仿真循环 │
│ while True: │
│ stepSimulation() │
│ getBasePositionAndOrientation() │
│ (可视化 / 控制 / 数据记录) │
│ time.sleep(dt) │
└────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────┐
│ 6️⃣ 断开连接(清理资源) │
│ disconnect() │
└────────────────────────────────────────────┘
💻 完整 Python 示例代码
python
import pybullet as p
import pybullet_data
import time
# 1️⃣ 连接物理引擎(GUI模式可视化 / DIRECT模式无界面)
physicsClient = p.connect(p.GUI) # 或者 p.DIRECT
# 2️⃣ 设置仿真环境参数
p.setAdditionalSearchPath(pybullet_data.getDataPath()) # 加载官方模型路径
p.setGravity(0, 0, -9.8)
p.setTimeStep(1.0 / 240.0)
# 3️⃣ 创建地面和平面
plane_id = p.loadURDF("plane.urdf")
# 也可以自定义形状:
# collision = p.createCollisionShape(p.GEOM_BOX, halfExtents=[1,1,0.1])
# body = p.createMultiBody(baseMass=0, baseCollisionShapeIndex=collision)
# 4️⃣ 创建一个机器人或简单物体(例如球体)
start_pos = [0, 0, 1]
start_orn = p.getQuaternionFromEuler([0, 0, 0])
ball_collision = p.createCollisionShape(p.GEOM_SPHERE, radius=0.1)
ball_visual = p.createVisualShape(p.GEOM_SPHERE, radius=0.1, rgbaColor=[1, 0, 0, 1])
ball_id = p.createMultiBody(baseMass=1,
baseCollisionShapeIndex=ball_collision,
baseVisualShapeIndex=ball_visual,
basePosition=start_pos,
baseOrientation=start_orn)
# 5️⃣ 仿真主循环
for i in range(240 * 5): # 模拟5秒(240Hz)
p.stepSimulation()
pos, orn = p.getBasePositionAndOrientation(ball_id)
print(f"Step {i}: pos={pos}, orn={orn}")
time.sleep(1.0 / 240.0) # 实时同步
# 6️⃣ 断开连接
p.disconnect()
📘 总结要点
阶段 | 主要函数 | 说明 |
---|---|---|
初始化 | connect() |
连接到物理引擎服务器 |
环境设置 | setGravity() , setTimeStep() |
设置仿真参数 |
加载模型 | loadURDF() / createMultiBody() |
加载或自定义刚体 |
状态初始化 | resetBasePositionAndOrientation() |
重置初始位置姿态 |
仿真推进 | stepSimulation() |
执行一步仿真(前向动力学、碰撞检测等) |
数据读取 | getBasePositionAndOrientation() |
获取状态信息 |
清理退出 | disconnect() |
关闭物理引擎 |