pybullet入门到入门_1

文章目录

  • 安装
  • 介绍
    • [🧩 一、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)

  1. 安装C++编译工具
    pybullet 需要C++编译套件,直接装之前检查下,要不会报缺少某版本MVSC的error,最好的方式是直接下载visual studio,直接按默认选的组件来装,装的磁盘位置可以自定义。
  1. 安装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 教程 / 机器人仿真"

💡 七、学习建议

  1. 先跑通 GUI 示例 → 熟悉 API
  2. 学 URDF/MJCF 文件结构 → 会修改机器人模型
  3. 做一个控制项目 → 例如机械臂抓取
  4. 结合 RL 环境 → 学会调用 Gym 接口
  5. 阅读源码与 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 可以很方便地与 TensorFlowOpenAI 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)
  • 如果是 DIRECTGUI,会关闭仿真引擎。
  • 如果是远程物理服务器,则服务器继续运行。

✅ 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 模式下无效。
  • GUIVRTCP/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() 关闭物理引擎

相关推荐
ccLianLian几秒前
计算机视觉·ZegFormer
人工智能·计算机视觉
wjs20242 分钟前
Go 语言切片(Slice)
开发语言
i查拉图斯特拉如是5 分钟前
Coze工作流意图识别
人工智能·大模型·工作流·意图识别·coze
坚持就完事了5 分钟前
数据结构之链表
数据结构·python·算法·链表
创客匠人老蒋5 分钟前
穿越周期的发展动力:创始人IP与AI融合下的成长路径解析
人工智能·创客匠人全球ip+ai高峰论坛·全球创始人ip+ai万人峰会
灰灰学姐5 分钟前
注意力机制
人工智能·深度学习·机器学习
muyouking117 分钟前
Rust Slice 完全指南:从基础用法到 3D 场景实战
开发语言·3d·rust
m0_650108249 分钟前
Don’t Shake the Wheel: 端到端自动驾驶中的动量感知规划(MomAD)
人工智能·自动驾驶·端到端·实时性·动量感知机制·闭环性能·长时域预测
懂AI的老郑9 分钟前
自动驾驶之眼:动态目标理解的关键突破
人工智能
大模型服务器厂商10 分钟前
挥手示意车辆先行,自动驾驶为何常 “不知所措”? Alpamayo-R1给出新解法
人工智能·机器学习·自动驾驶