完全免费的pybullet手册中文版!

PyBullet 快速入门指南

Erwin Coumans, Yunfei Bai, 2016-2023

访问桌面文档、论坛、github 讨论并为 Bullet 点赞!

合成相机渲染 48

计算视图/投影矩阵 48

获取相机图像 49

获取视觉形状数据 52

改变视觉形状,加载纹理 53

碰撞检测查询 53

获取重叠对象,获取AABB 53

getContactPoints, getClosestPoints 54

rayTest, rayTestBatch 56

启用/禁用碰撞 58

第 2 页

简介

PyBullet 是一个用于机器人模拟和机器学习的快速且易于使用的 Python 模块,重点放在模拟到现实世界转移上。使用 PyBullet 可以加载来自 URDF、SDF、MJCF 和其他文件格式的关节刚体。PyBullet 提供了正向动力学模拟、反向动力学计算、正向/逆向运动学、碰撞检测和光线交集查询等功能。Bullet 物理引擎 SDK 包括了几个 PyBullet 机器人示例,如模拟的迷你四足动物、使用 TensorFlow 推断的人形机器人跑步,以及 KUKA 手臂抓取物体。由统一的 LCP 约束求解器处理缩减坐标多体、刚体和可变形体,与本论文中的 Articulated Islands 算法类似,它使用 Articulated Body 算法进行线性时间正向动力学并创建求解器矩阵 A。

除了 物理模拟,还有 渲染绑定,包括 CPU 渲染器(TinyRenderer)和 OpenGL 3.x 渲染和可视化,以及 对诸如 HTC Vive 和 Oculus Rift 等虚拟现实耳机的支持。PyBullet 还具有执行碰撞检测查询的功能(最近点、重叠对、射线相交测试等),并添加调试渲染功能(调试线和文本)。PyBullet 具有跨平台内置客户端-服务器共享内存支持,UDP 和 TCP 网络。因此,您可以在连接到 Windows VR 服务器的 Linux 上运行 PyBullet。

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 配合使用。Google Brain [1][2][3][4]、X [1][2]、斯坦福人工智能实验室 [1][2][3]、OpenAI、INRIA [1] 等许多实验室都在使用 PyBullet。如果您在研究中使用了 PyBullet,请添加参考文献。

安装PyBullet很简单,就像这样(使用sudo)pip install PyBullet (Python 2.x),或者pip3 install PyBullet。这会暴露PyBullet模块以及pybullet_envs Gym环境。

第 3 页

你好,PyBullet世界

以下是我们在每一步中讨论的 PyBullet 介绍脚本:

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) p.resetBasePositionAndOrientation(boxId, startPos, startOrientation) for i in range(10000): p.stepSimulation()

time.sleep(1./240.)

cubePos, cubeOrn = p.getBasePositionAndOrientation( boxId ) print(cubePos,cubeOrn)

断开连接。

连接,断开,子弹客户端

在导入PyBullet模块后,首先要做的就是“连接”到物理模拟。PyBullet 是基于客户端 - 服务器驱动的 API 设计的,其中客户端发送命令,而物理服务器返回状态。PyBullet 包含一些内置的物理服务器:DIRECT 和 GUI。GUI 和 DIRECT 连接将在与 PyBullet 同一进程中执行物理模拟和渲染。

注意,在 DIRECT 模式下,您无法访问 OpenGL 和 VR 硬件功能,如“虚拟现实”和“调试用户界面、线、文本、参数”章节中所述。DIRECT 模式允许通过 getCameraImage API 使用内置软件渲染器来呈现图像。这对于在没有 GPU 的服务器上运行云端模拟非常有用。

你可以提供自己的数据文件,或者使用随PyBullet一起提供的 PyBullet_data软件包。为此,请导入pybullet_data并使用 pybullet.setAdditionalSearchPath(pybullet_data.getDataPath()) 注册目录。

第 4 页

getConnectionInfo

给定一个 物理 客户端 ID,将返回 [是否连接,连接方法] 的列表。

已连接

如果给定一个physicsClientId, isConnected 会返回true 如果已连接,否则返回false。

设置超时

如果服务器在特定时间内没有处理命令,客户端将会断开连接。使用 setTimeout() 来设置以秒为单位的时间值。

使用DIRECT、GUI 连接。

直接连接直接把命令发送到物理引擎,不使用任何传输层和图形可视化窗口,并在执行命令后直接返回状态。

GUI 连接将在与 PyBullet 同一进程空间内创建一个新的图形用户界面 (GUI),使用 3D OpenGL 渲染。在 Linux 和 Windows 上,该 GUI 在一个单独的线程中运行,而在 macOS 上由于操作系统限制,它在相同的线程中运行。在 macOS 上,您可能会看到 OpenGL 窗口中旋转的轮子,直到您调用 stepSimulation 或其他 PyBullet 命令。

第 5 页

命令和状态信息通过普通的内存缓冲区在 PyBullet 客户端和 GUI 物理模拟服务器之间传递。

也可以使用 共享内存、UDP 或 TCP 网络 从同一台机器上的不同进程或远程机器连接到物理服务器。参见共享内存、UDP 和 TCP 部分了解详情。

由于向后兼容性,与其他方法不同的是,这种方法不解析关键字参数。

连接输入参数如下:

第 6 页

connect 返回一个 物理引擎客户端ID,如果未连接则返回 -1。物理引擎客户端 ID 是大多数其他 PyBullet 命令的可选参数。如果您不提供它,则会假定 物理引擎客户端ID = 0。您可以连接到多个不同的物理服务器,除了 GUI。

例如:

pybullet.connect(pybullet.DIRECT)

pybullet.connect( pybullet.Gui(), options='--opengl2')

pybullet.connect(共享内存,1234)

pybullet.connect( pybullet.UDP, "192.168.0.1")

pybullet.connect( pybullet.UDP, "localhost", 1234)

pybullet.connect( pybullet.TCP, "localhost", 6667 )

使用共享内存连接。

有几台物理服务器允许共享内存连接:

App_SharedMemoryPhysics、App_SharedMemoryPhysics GUI 和 Bullet 示例浏览器 在 Experimental/PhysicsServer 下有一个示例,可以进行共享内存连接。 这样就可以在单独的进程中执行物理模拟和渲染。

您还可以通过共享内存连接到 App_SharedMemoryPhysics_VR,这是一款支持头戴式显示器和六自由度跟踪控制器(如HTC Vive和Oculus Rift Touch)的虚拟现实应用程序。由于Valve OpenVR SDK只在Windows下正常工作,因此App_SharedMemoryPhysics_VR 只能使用premake(最好)或cmake 在Windows下构建。

使用UDP或TCP网络连接

对于 UDP 网络,有一个名为 App_PhysicsServerUDP 的应用程序监听特定的 UDP 端口。它使用开源库 enet 以实现可靠的 UDP 网络。这使得您可以在单独的机器上执行物理模拟和渲染。PyBullet 使用 clsocket 库进行 TCP 连接。当从防火墙后面的计算机到机器人仿真之间使用 SSH 隧道时,此功能可能会很有用。例如,您可以使用 PyBullet 在 Linux 上运行控制堆栈或机器学习,同时在虚拟现实环境中使用HTC Vive 或 Rift 运行Windows 物理服务器。

第 7 页

另一个 UDP 应用程序是 App_PhysicsServerSharedMemoryBridgeUDP,它充当到现有物理服务器的桥梁:您可以使用 UDP 连接到该桥接器,而桥接器则使用共享内存连接到物理服务器:桥接器在客户端和服务器之间传递消息。类似地,还有一个 TCP 版本(用 TCP 替换 UDP)。

还有GRPC客户端和服务器支持,但默认情况下未启用。您可以使用premake4构建系统通过--enable_grpc选项进行尝试(参见Bullet / build3 / premake4)。

注意:目前,客户端和服务器端必须都是32位或64位构建!

子弹客户端

如果你想并行使用多个独立模拟,可以使用pybullet_utils.bullet_client。一个实例:

bullet_client.BulletClient(connection_mode=pybullet.Gui, options="") 具有与 pybullet 实例相同的 API。它会自动为每个 API 调用添加适当的 physicsClientId。PyBullet Gym 环境使用 bullet_client 来允许在

平行,参见env_bases.py中的实现。另一个小例子展示了如何拥有两个独立的实例,每个都有自己的对象,参见multipleScenes.py。

断开连接

你可以通过使用 connect() 返回的物理服务器客户端 ID 来断开与物理服务器的连接(如果该值为非负数)。"DIRECT" 或 "GUI" 物理服务器将会关闭。一个独立的

(进程外) 物理服务器会继续运行。 请参阅 resetSimulation 以删除所有项目。

断开连接参数:

设置重力

默认情况下,不会启用重力。 setGravity 允许您为所有对象设置默认的重力。

setGravity 的输入参数为:(无返回值)

第 8 页

loadURDF,loadSDF,loadMJCF

loadURDF 将向物理服务器发送一个命令,以从通用机器人描述文件 (URDF) 加载一个物理模型。URDF 文件由 ROS 项目(机器人操作系统)用于描述机器人和其他对象。它是由 Willow Garage 和开源机器人基金会 (OSRF) 创建的。许多机器人都有公开的 URDF 文件,你可以在这里找到描述和教程:urdf/Tutorials - ROS Wiki

重要提示:大多数关节(滑块、旋转、连续)默认启用电机,以防止自由运动。这类似于具有高摩擦谐波驱动器的机器人关节。您应该使用pybullet.setJointMotorControl2设置关节电机控制模式和目标设置。了解有关setJointMotorControl2 API的更多信息。

警告:默认情况下,PyBullet 会缓存一些文件以加快加载速度。您可以使用 setPhysicsEngineParameter() 来禁用文件缓存(设置 enableFileCaching = 0)。

loadURDF 的参数为:

第 10 页

loadURDF() 返回一个身体唯一标识符,即非负整数值。如果无法加载URDF文件,则返回None。

如果这个整数被加载了,那么它将是负的并且不是一个有效的身体唯一标识。默认情况下,loadURDF 将使用凸多边形进行网格碰撞检测。对于静态(质量为零,不移动)网格,您可以通过在 URDF 中添加标签来使网格变凹: 参见 samurai.urdf 以获取示例。URDF 格式有一些其他扩展,您可以浏览示例以了解更多信息。PyBullet 不会处理来自 URDF 文件的所有信息。查看示例和 URDF 文件以了解哪些功能受支持。通常有一个 Python API 来控制这些功能。每个链接只能有一个材料,因此如果您有多个具有不同材料的视觉形状,则需要将它们拆分为单独的链接,并通过固定关节连接起来。您可以使用 Bullet 集成中的 OBJ2SDF 工具来完成此操作。

加载 SDF 文件,加载 MJCF 格式文件

您还可以从其他文件格式加载对象,例如 .bullet、.sdf 和 .mjcf。 这些文件格式支持多个对象,因此返回值是对象唯一标识符的列表。 有关 SDF 格式的详细信息,请参阅http://sdformat.org。 loadSDF 命令仅提取与机器人模型和几何形状相关的 SDF 的一些基本部分,并忽略许多与相机、灯光等相关的元素。 loadMJCF 命令执行用于 OpenAI Gym 的 MuJoCo MJCF XML 文件的基本导入。 请参阅loadURDF下方的重要注意事项中的默认关节电机设置,并确保使用setJointMotorControl2。

第 11 页

loadBullet、loadSDF 和 loadMJCF 返回一个包含对象唯一标识符的数组:

保存状态, 保存子弹, 恢复状态

当您需要在还原到之前保存的状态后进行确定性模拟时,包括接触点在内的所有重要状态信息都需要被存储。 仅使用saveWorld 命令不足以实现这一点。 您可以使用restoreState命令从 saveState (in-memory) 或 saveBullet (on disk) 中创建的快照中恢复。

saveState 命令只接受一个可选的客户端服务器 ID 作为输入,并返回状态 ID。saveBullet 命令将在磁盘上的 a.bullet 文件中保存状态。restoreState 命令的输入参数如下:

文件名或状态 ID 需要有效。注意,restoreState 将重置对象的位置和关节角度,并恢复接触点信息。在调用 restoreState 之前,请确保已经设置好了对象和约束条件。参见 saveRestoreState.py 示例。

移除状态

removeState 允许从内存中删除之前存储的状态。

保存世界

你可以创建一个近似的世界快照,作为存储在服务器上的 PyBullet Python 文件。saveWorld 可以作为一个基本编辑功能,例如设置机器人、关节角度、物体位置和虚拟现实环境。稍后您可以加载 PyBullet Python 文件重新创建世界。python 快照包含 loadURDF 命令以及初始化关节角度和对象变换。请注意,并非所有设置都保存在世界文件中。

输入参数如下:

第 12 页

创建碰撞形状/视觉形状

虽然在世界中创建东西最推荐和最简单的方法是使用加载函数(loadURDF/SDF/MJCF/Bullet),但您也可以通过编程方式创建碰撞体和视觉形状,并使用它们来创建多刚体,使用createMultiBody。参见Bullet 物理引擎SDK中的createMultiBodyLinks.py 和 createVisualShape.py 示例。

第 13 页

返回值是非负整数,表示碰撞形状的唯一标识符,如果调用失败则为 -1。

创建碰撞形状数组

collisionShapeArray 是 createCollisionShape 的数组版本。有关用法,请参阅 snake.py 或 createVisualShapeArray.py 示例,了解如何使用它。

移除碰撞形状

removeCollisionShape() 通过碰撞形状的唯一标识符移除现有的碰撞形状。

创建视觉形状

你可以通过创建碰撞形状的方式来创建一个可视形状,但是你需要提供一些额外的参数来控制外观,比如漫反射颜色和镜面高光颜色。当你使用GEOM_MESH 类型时,你可以指向一个Wavefront OBJ文件,这个可视形状会从材质文件 (.mtl) 中解析出一些参数,并加载纹理贴图。注意,大型纹理(大于1024x1024 像素)可能会降低加载和运行时性能。

查看示例文件夹中的 addPlanarReflection.py 和 createVisualShape.py。

第 14 页

输入参数为

第 15 页

返回值 是视觉形状的非负整数唯一标识符,或者如果调用失败,则为 -1 。 请参阅 createVisualShape、createVisualShapeArray 和 createTexturedMeshVisualShape 示例。

创建视觉形状数组

createVisualShapeArray 是 createVisualShape 的数组版本。参见 createVisualShapeArray.py 示例。

创建多体

虽然使用加载函数(loadURDF/SDF/MJCF/Bullet)在世界中创建东西是最简单的方法,但你可以使用createMultiBody来创建一个多体。请参阅Bullet Physics SDK 中的createMultiBodyLinks.py示例。createMultiBody 的参数与URDF 和SDF 参数非常相似。

你可以创建一个只有一个基座但没有关节/子链接的多体,或者你可以创建一个多体与关节/子链接。如果你提供链接,请确保每个列表的长度相同(例如len(linkMasses)== len(linkCollisionShapeIndices))。createMultiBody 的输入参数为:

第 16 页

createMultiBody 的返回值是一个非负的唯一标识符,或者是失败时的 -1。例如:

cuid = pybullet. 创建碰撞形状 (pybullet. GEOM_ 箱子, 半径= [1, 1, 1])

质量=0 #静态盒子

pybullet.createMultiBody(mass, cuid)

参见 Bullet/examples/pybullet/examples 文件夹中的 createMultiBodyLinks.py、createObstacleCourse.py 和 createVisualShape.py。

获取网格数据

getMeshData 是一个实验性的未公开的 API,用于返回三角形网格的网格信息(顶点、索引)。

第 17 页

stepSimulation, 进行碰撞检测

stepSimulation 将在单个正向动力学模拟步骤中执行所有操作,例如碰撞检测、约束求解和积分。默认时间步长为 1/240 秒,可以使用 setTimeStep 或 setPhysicsEngineParameter API 进行更改。

默认情况下,stepSimulation 没有返回值。

仅限实验/高级使用:如果通过 setPhysicsEngineParameter API 启用了 reportSolverAnalytics,则会返回以下详细信息的岛屿列表:

参见 setRealTimeSimulation 以让物理服务器根据其实时时钟自动运行正向动力学模拟。

第 18 页

执行碰撞检测

performCollisionDetection API 将执行 stepSimulation 中的碰撞检测阶段。唯一需要的参数是 physicsClientId。在发出此调用后,您可以使用 getContactPoints。

设置实时模拟

默认情况下,除非您明确发送一个

“stepSimulation”命令。这样可以保持模拟的确定性。你可以通过设置实时模拟来让 物理服务器根据其时钟(RTC) 自动对模拟进行实时步进。 如果启用了实时模拟,则无需调用“stepSimulation”。

注意,setRealTimeSimulation 在 DIRECT 模式下没有效果:在 DIRECT 模式中,物理服务器和客户端都在同一个线程中,并且您会触发每个命令。在 GUI 模式、虚拟现实模式以及 TCP/UDP 模式中,物理服务器与客户端(PyBullet)运行在不同的线程中,而 setRealTimeSimulation 允许物理服务器线程添加额外的调用以进行仿真。

输入参数如下:

获取基位置和方向

getBasePositionAndOrientation 以笛卡尔世界坐标系中报告身体的基座(或根链)的当前位置和方向。 方向是 [x, y, z, w] 格式的四元数。

第 19 页

getBasePositionAndOrientation 返回一个包含三个浮点数的位置列表和一个包含四个浮点数的朝向列表,以 [x, y, z, w] 的顺序排列。如果需要的话,可以使用 getEulerFromQuaternion 将四元数转换为欧拉角。

参见重置基座位置和方向以重置对象的位置和方向。

这完成了第一个PyBullet脚本。Bullet附带了几个URDF文件在Bullet / data文件夹中。

重置基座位置与朝向

你可以重置每个对象的基座(根)的位置和朝向。最好只在开始时进行此操作,而不是在运行模拟时,因为该命令会覆盖所有物理模拟的效果。线性和角速度都设置为零。可以使用 resetBaseVelocity 以非零的线性和/或角速度重置。

没有返回值。

变换:位置和方向

物体的位置可以表示为笛卡尔世界空间坐标系下的 [x,y,z]。物体的方向(或旋转)可以用四元数[x,y,z,w]、欧拉角[roll,pitch,yaw] 或者 3x3 矩阵来表示。PyBullet 提供了一些辅助函数,用于在四元数、欧拉角和 3x3 矩阵之间进行转换。此外还有一些函数可用于矩阵乘法和求逆。

从欧拉角获取四元数 getQuaternionFromEuler 和 从四元数获取欧拉角 getEulerFromQuaternion

PyBullet API 使用四元数来表示方向。由于人们不直观理解四元数,因此有两个 API 可以在四元数和欧拉角之间进行转换。

getQuaternionFromEuler 的输入参数如下:

提问

复制

添加至笔记

第 20 页

getQuaternionFromEuler() 返回一个包含四个浮点数的 vec4 列表 [X, Y, Z, W]。

从四元数中获取欧拉角

getEulerFromQuaternion 返回一个包含三个浮点数的列表,即 vec3。旋转顺序是 首先绕X轴旋转,然后绕Y轴旋转,最后绕Z轴旋转,与 ROS URDF rpy 兼容。

从四元数获取矩阵

getMatrixFromQuaternion 是一个实用程序 API,用于从四元数创建 3x3 矩阵。输入为四元数,输出为一个包含 9 个浮点数的列表,表示矩阵。

从四元数获取轴角

getAxisAngleFromQuaternion 将返回给定四元数方向的轴和角度表示。

乘变换,反变换

PyBullet 提供了一些帮助函数来计算变换矩阵的乘法和逆。这可以帮助我们在不同的坐标系之间转换坐标。

multiplyTransforms 的输入参数如下:

第 21 页

返回值是一个包含位置(vec3)和方向(vec4,四元数 x、y、x 和 w)的列表。

invertTransform 的输出是一个位置(vec3)和一个方向(vec4,四元数x,y,z,w)。

获取差异四元数

getDifferenceQuaternion 会返回一个四元数,用于插值从起始方向到结束方向。

获取 API 版本号

你可以用年月日格式查询 API 版本。只能连接相同 API 版本、位数(32 位或 64 位)的物理客户端/服务器。

为了保持 API 一致性,新增了一个可选未使用的参数 physicsClientID。

第 22 页

控制机器人

在引言中,我们已经展示了如何初始化 PyBullet 并加载一些对象。如果你用“r2d2.urdf”替换了 loadURDF 命令中的文件名,你可以模拟一个从 ROS 教程中获得的 R2D2 机器人。让我们控制这个 R2D2 机器人移动、四处张望并控制机械臂。为此,我们需要知道如何访问它的关节电机。

底座、关节、连杆

在描述为 URDF 文件的模拟机器人中,有一个基座,并且可选地连接有连杆。每个关节连接一个父链接到子链接。层次结构的根部有一个单独的根父链接,我们称其为基础。基础可以是完全固定的(零自由度),也可以是完全自由的(六个自由度)。由于每个链接通过单个关节连接到父链接,因此关节的数量等于链接数。普通链接具有在 [0 .. getNumJoints()) 范围内的链接索引。由于基础不是“常规”链接,因此我们使用 -1 作为其链接索引,但是大多数与链接相关的 API 只接受链接索引 >= 0 的常规链接。我们约定关节框架相对于惯性参考系的质心对齐,即沿着惯性主轴。

getNumJoints, getJointInfo

加载机器人后,您可以使用 getNumJoints 接口查询关节数量。对于 r2d2.urdf 来说,这应该返回 15。

getNumJoints 输入参数:

第 23 页

getNumJoints() 返回一个表示关节数量的整数值。

获取关节信息

对于每个关节,我们可以查询一些信息,如它的名字和类型。

获取关节信息输入参数

getJointInfo() 返回关节信息列表:

第 24 页

设置关节电机控制 2/数组

注意:setJointMotorControl 是过时的,已由 setJointMotorControl2 API 取代。(甚至更好的做法是使用 setJointMotorControlArray)。

我们可以通过为一个或多个关节电机设置所需的控制模式来控制机器人。在 步进 模拟中,物理引擎会模拟电机以达到给定的目标值,该目标值可以在最大电机力和其他约束内实现。

重要提示:默认情况下,每个旋转关节和线性关节都使用一个速度电机来驱动。你可以通过设置最大力为零来禁用这些默认驱动器。这将允许你对扭矩进行控制。

例如:

最大力 = 0

模式 = 速度控制。

p.setJointMotorControl2(对象标识符,关节索引,)

控制模式=模式,强制力=最大力量)

您还可以使用微小但非零的力量来模拟关节摩擦。

如果你想让一个轮子保持恒定的速度,你可以使用最大的力:

最大力 = 500

p.setJointMotorControl2(bodyUniqueId=objUid,

联合索引 = 0,

控制模式=加速度,

目标速度 = 目标速度,

强制 = 最大力量)

setJointMotorControl2 的输入参数为:

第 25 页

注意:联合电机控制器的实际实现作为位置控制和速度控制的约束,以及扭矩控制的外部力:

通常情况下,最好从VELOCITY_CONTROL或POSITION_CONTROL开始。 因为模拟正确的力取决于非常准确的URDF / SDF文件参数和系统识别(正确质量、惯性、质心位置、关节摩擦等),所以做TORQUE_CONTROL(力控制)要困难得多。

第 26 页

设置关节电机控制数组

你可以通过传递数组来减少每个联合调用的开销,而不是为每个联合单独调用。

setJointMotorControlArray 接受与 setJointMotorControl2 相同的参数,除了整数被整数列表替换。

setJointMotorControlArray 的输入参数如下:

参见 bullet3/examples/pybullet/tensorflow/humanoid_running.py 中使用 setJointMotorControlArray 的示例。

设置关节多轴电机控制

setJointMotorControlMultiDof与setJointMotorControl2类似,但是它支持球形(多自由度)关节。这是在 deep_mimic 环境(pybullet_envs)和 humanoidMotionCapture.py 示例中使用的。targetPosition、targetVelocity 和 force 参数接受一个一维数组或三个一维数组来支持球形关节,而不是单个浮点数。

setJointMotorControlMultiDof 的输入参数为:

第 27 页

设置关节多轴电机控制数组

setJointMotorControlMultiDofArray 是 setJointMotorControlMultiDof 的更高效版本,通过传递多个控制目标来避免/减少在 Python 和之间调用开销。

PyBullet 的 C++ 扩展。参见 humanoidMotionCapture.py 以获取示例。

第 28 页

获取关节状态,重置关节状态

我们可以使用 getJointState 从关节获取多个状态变量,例如 关节位置、速度、力矩。

getJointState 输入参数

第 29 页

获取关节状态

getJointStates 是 getJointState 的数组版本。 与其传递单个关节索引,不如传递一个关节索引列表。

获取多关节状态

球形关节还有getJointStateMultiDof。

获取关节状态输出

获取多关节状态

getJointStatesMultiDof 允许查询多个关节状态,包括多 DOF(球形)关节。

第 30 页

重置关节状态

你可以重置关节状态。最好只在不运行模拟的情况下进行此操作:resetJointState 将覆盖所有物理模拟。请注意,目前我们仅支持最多一个自由度的电机驱动关节,滑动关节或旋转关节。

重置关节状态 (s) 多 DOF

还有用于球形关节的重置关节状态多 DOF。 看一下 humanoidMotionCapture 中的 重置关节状态多 DOF 示例。 同时也有一个 重置多个关节 的重置关节状态多 DOF。

启用关节力矩传感器

您可以启用或禁用每个关节的联合力/扭矩传感器。一旦启用,如果执行一步 模拟,“getJointState” 将报告固定自由度中的关节反作用力:一个固定的关节会测量所有六个方向上的关节力矩。旋转/铰链关节的力/扭矩传感器将沿除铰接轴以外的所有轴测量五个方向上的反应力。关节电机施加的力在 getJointState 的 appliedJointMotorTorque 中可用。

第 31 页

获取链接状态(s)

您还可以使用getLinkState查询每个链接质心在笛卡尔世界中的位置和方向。它还将质心的局部惯性参考系报告给URDF链接框架,以便更容易计算图形/可视化框架。

getLinkState 返回值

获取链接状态

第 32 页

getLinkStates 将返回多个链接的信息。它接受一个整数列表作为参数,而不是单个链接索引。这样可以提高性能,减少多次调用 getLinkState 的开销。

示例脚本(可能已过时,请检查实际Bullet/examples/pybullet/examples文件夹。)

第 33 页

获取基线速度,重置基线速度

使用getBaseVelocity()可以获得身体基座的速度和角速度。 输入参数如下:

这会返回一个包含两个向量 3 值(列表中的三个浮点数)的列表,这些值表示笛卡尔世界空间坐标系中的线性速度 [x, y, z] 和角速度 [wx, wy, wz]。

你可以使用resetBaseVelocity来重置一个刚体的线性和/或角速度。输入参数为:

应用外部力/扭矩

你可以使用applyExternalForce和applyExternalTorque对刚体施加力或扭矩。注意,只有在明确使用stepSimulation时此方法才有效,换句话说:setRealTimeSimulation(0)。每次模拟步骤后,外部力被清除为零。如果你使用的是setRealTimeSimulation(1),则applyExternalForce/Torque的行为将是未定义的(可能是0、1或多次施加力/扭矩)。

第 34 页

getNumBodies,getBodyInfo,getBodyUniqueId,removeBody。

getNumBodies 会返回物理服务器中的实体总数。 如果您使用了’getNumBodies‘,则可以使用’getBodyUniqueId‘ 来查询实体唯一标识符。 注意:所有 API 都已经返回了实体唯一标识符,所以如果您一直记录它们的话,那么通常情况下您不需要使用 getBodyUniqueId。

getBodyInfo 将返回从 URDF、SDF、MJCF 或其他文件中提取出的基础名称和身体名称。

同步身体信息

syncBodyInfo 会同步多个客户端连接到一个物理服务器时,改变世界(loadURDF、removeBody 等)的身体信息(getBodyInfo)。

removeBody 通过其身体唯一标识符(来自 loadURDF、loadSDF 等)移除一个身体。

创建约束,移除约束,改变约束

URDF、SDF 和 MJCF 使用树结构来定义关节体,没有环。'createConstraint' 允许您连接身体的特定链接以闭合环。参见Bullet/examples/pybullet/examples/quadruped.py 关于如何连接四足动物的五杆闭合环连杆。此外,您可以创建任意的对象之间的约束,以及对象与特定世界框架之间的约束。参见

请参阅 bullet/examples/pybullet/examples/constraint.py 以获取示例。

它也可以用来控制物理对象的运动,比如驱动动画帧的 VR 控制器。对于这种目的,最好使用约束,而不是直接设置位置或速度,因为这些约束会与其他动力学约束一起求解。

createConstraint 有以下输入参数:

第 35 页

createConstraint 将返回一个整数唯一标识符,可用于更改或删除约束。 有关 JOINT_GEAR 的示例,请参阅 examples/pybullet/examples/mimicJointConstraint.py;有关 JOINT_POINT2POINT 的示例,请参阅 examples/pybullet/examples/minitaur.py;有关 JOINT_FIXED 的示例,请参阅 examples/pybullet/examples/constraint.py。

改变约束

changeConstraint 允许您更改现有约束的参数。输入参数如下:

第 36 页

getNumConstraints,getConstraintUniqueId

你可以查询使用“createConstraint”创建的约束总数。 可选参数是整数physicsClientId。

获取约束唯一标识符

getConstraintUniqueId 将从 0 到 getNumConstraints 范围内的连续索引转换为约束唯一标识符。请注意,由于您可能会删除约束,因此约束唯一标识符可能不是连续的。输入参数为整数序列索引,可选参数为 physicsClientId。

获取约束信息/状态

你可以通过约束唯一标识查询约束信息。

输入参数为

输出列表为:

第 37 页

获取约束状态

给约束一个唯一的 ID,这样就可以查询最近一步模拟中施加的约束力。输入是一个约束的唯一ID,输出是一组约束力向量,其维度是受约束影响的自由度(例如,固定约束会影响6个自由度)。

获取动力学信息/改变动力学

你可以获取有关基础、质心、摩擦和其他组件的信息。

返回信息有限,我们会在需要时披露更多信息:

第 38 页

改变动态

你可以使用 changeDynamics 改变 物理属性,如质量、摩擦系数和恢复系数。

输入参数如下:

第 40 页

设置时间步长

警告:在大多数情况下,最好将时间步长保留在默认值240Hz。有几个参数是针对此值进行调整的。例如,求解器迭代次数以及与时间步长相关的接触、摩擦和非接触关节的误差减少参数ERP。如果您更改了时间步长,您可能需要相应地重新调整这些值,特别是ERP值。

你可以设置在调用“stepSimulation”时使用的物理引擎时间步。最好只在模拟开始时调用这个方法。不要定期更改此时间步长。也可以使用新的setPhysicsEngineParameter API 来设置时间步长。

输入参数如下:

设置 物理 引擎 参数

您可以使用 setPhysicsEngineParameter API 设置 物理引擎参数。 以下参数是公开的:

第 42 页

setDefaultContactERP 是设置默认接触参数的 API。它将会被包含在 setPhysicsEngineParameter 中。

第 43 页

获取 物理 引擎 参数

你可以使用 getPhysicsEngineParameters 命令查询一些当前 物理引擎参数,使用可选的 'physicsClientId'。这会返回一个命名元组的参数。

重置模拟。

重置模拟将从世界中删除所有对象,并将世界重置为初始条件。

它接受一个可选参数: 物理客户端 ID(如果您创建了多个物理服务器连接)。

开始记录状态/停止记录状态

状态日志让您能够记录模拟的状态,例如每个仿真步骤(在每次调用stepSimulation时)或启用实时仿真后每步自动记录一次仿真状态。这使您能够记录对象轨迹。还有记录身体常见状态的选项,如基位置和方向、关节位置(角度)和关节电机力。

使用 startStateLogging 生成的所有日志文件都可以通过 C++ 或 Python 脚本进行读取。查看 quadruped_playback.py 和 kuka_with_cube_playback.py 中的 Python 脚本,了解如何读取日志文件。你可以使用 bullet3/examples/Utils/RobotLoggingUtil.cpp/h 在 C++ 中读取日志文件。

对于 MP4 视频录制,可以使用日志选项 STATE_LOGGING_VIDEO_MP4。我们计划实现各种其他类型的日志记录,包括 VR 控制器状态的日志记录。

作为特殊情况,我们实现了 Minitaur 机器人的日志记录。PyBullet 模拟的日志文件与真正的 Minitaur 四足动物的日志文件相同。参见 Bullet/examples/pybullet/examples/logMinitaur.py 以获取示例。

重要:各种日志记录器都包含自己的内部时间戳,该时间戳在创建时从零开始。这意味着您需要同时启动所有日志记录器,以使其同步。您需要使

第 44 页

确保在启动日志记录器之前,模拟不是实时模式:在创建日志记录器之前使用 pybullet.setRealTimeSimulation(0)。

第 45 页

该命令会返回一个非负整数loggingUniqueId,可以与stopStateLogging一起使用。

需要:为每种日志类型记录的日志数据编写文档。目前,可以使用日志读取工具来查找,或者查看日志或Python 的 dumpLog.py 脚本的C ++源代码。

停止状态日志记录

你可以通过日志记录器的loggingUniqueId来停止一个日志记录器。

提交个人资料时程表

submitProfileTiming 可以用来插入起始时间和停止时间来为Python代码打日志。查看profileTiming.py示例。

PyBullet 和 Bullet 已经为许多函数添加了计时器,因此您可以查看时间花在哪里。您可以在文件中导出这些性能计时,并使用谷歌Chrome浏览器中的 about://tracing 窗口加载它们。在图形用户界面 (GUI) 中,您可以按下“P”键来开始或停止性能计时的导出。在某些情况下,您可能希望对客户端代码进行计时。您可以使用 PyBullet 提交性能计时。这是一个示例输出:

可变形物体和布料(有限元法,粒子位移模拟)

除了刚体多体和刚体动力学之外,PyBullet 还实现了可变形和布料模拟,使用有限元法(FEM)质量弹簧系统以及基于位置的动力学(PBD)。一些使用该实现的研究论文包括《使用有限元学习重新排列可变形电缆、织物和袋子与目标条件运输网络》(ICRA 2021),《用于可变形物体操作的仿真到现实强化学习》(使用 PBD) 和《辅助健身房:辅助机器人物理仿真的一个框架》(使用 PBD)。

第 46 页

PyBullet 实现了刚体/多体与变形体之间的双向耦合。双向耦合可用于碰撞,也可用于通过下面的 createSoftBodyAnchor 创建的手动附加物(参见下文)。

默认情况下,PyBullet 会使用基于位置的动力学(PBD)。您可以通过重置世界来启用基于有限元法(FEM)的模拟:

pybullet.resetSimulation(p.RESET_USE_DEFORMABLE_WORLD)

请参考 deformable_torus.py 作为示例。

加载软体模型/从URDF加载

有几种方法可以创建可变形对象,无论是布还是体积。loadSoftBody 可以从 vtk 或 obj 文件加载可变形对象。

loadSoftBody() 可以使用以下参数。注意,有几个参数假定您使用的是有限元模型,并且对粒子流体动力学模拟没有影响。

第 47 页

载入URDF

PyBullet 还扩展了 URDF 格式,以使用“deformable”标记来指定可变形对象。参见 例如 deformable_torus.urdf:

机器人名字为 "Torus"。

可变形名="环形体">

惯性参照系

惯性:ixx=0.0,ixy=0,ixz=0,iyy=0,iyz=0,izz=0。

以下是翻译结果:

你好,我叫Alex。我来自纽约市。我在哥伦比亚大学学习计算机科学,并计划在2025年毕业。我喜欢阅读、编程和探索新技术。我还在一家初创公司担任兼职工程师,帮助开发新产品。

很高兴认识你!

碰撞边距值为 0.006。

排斥刚度值为 800.0。

摩擦值=0.5。

neohookean mu=60 lambda=200 damping=0.01 </

< visual filename="torus.vtk"</

在本节中,我们定义了语义分割问题,并介绍了 前馈网络、卷积神经网络和递归神经网络。我们还介绍了一些流行的图像分类数据集。在下一章中,我们将讨论计算机视觉任务中的其他重要问题。

机器人: 我可以为您做些什么?

创建软体锚点

你可以通过使用 createSoftBodyAnchor 将可变形对象的顶点固定到世界中,或者将可变形对象的顶点附加到多体上。这会返回一个约束唯一标识符。您可以使用 removeConstraint API 删除此约束。

查看 deformable_anchor.py 以获取示例。

您可以使用 getMeshData() 接口访问可变形体的顶点。

第 48 页

合成相机渲染

PyBullet 包含一个内置的 OpenGL GPU 可视化工具,以及一个基于 TinyRenderer 的内置 CPU 渲染器。这使得从任意相机位置渲染图像变得非常容易。在 Linux 上,您还可以启用无 X11 上下文的硬件加速 OpenGL 渲染,例如用于谷歌云平台上的云计算或 Colab 中。请参阅“插件”部分中对 eglRenderTest.py 示例的说明,了解如何使用它。

合成相机由两个 4x4 矩阵定义:视图矩阵和投影矩阵。由于这些不是直观的,有一些辅助方法来计算可理解参数的视图和投影矩阵。

查看这篇关于 摄像机矩阵 的文章,内含 OpenGL摄像机信息 链接。

计算视图/投影矩阵

computeViewMatrix 的输入参数为

输出的是一个4×4视图矩阵,以一个包含16个浮点数的列表的形式存储。

计算从俯仰角、偏航角和滚转角得到的相机视图矩阵

输入参数为

第 49 页

输出的是一个4×4视图矩阵,以包含16个浮点数的列表的形式存储。

计算投影矩阵

输入参数为

输出为一个四行四列的投影矩阵,以一个包含16个浮点数的列表形式存储。

计算投影矩阵 - 视野

这个命令也会返回一个不同的参数的 4x4 投影矩阵。你可以查看 OpenGL 文档来了解这些参数的含义。

获取相机图像

getCameraImage 接口会返回每个像素的 RGB 图像、深度缓冲区以及包含可见对象身体唯一标识符的语义掩膜缓冲区。注意,可以使用 numpy 选项编译 PyBullet:使用 numpy 可以提高相机复制性能

第 50 页

从C到Python像素。注意:旧的渲染图像API已过时,已被getCameraImage取代。

getCameraImage 返回一个参数列表:

第 51 页

是否启用 numpy

注意,除非使用NumPy编译PyBullet,否则从C/C ++复制像素到Python对于大图像来说可能非常慢。你可以通过运行以下代码来检查NumPy是否启用:

PyBullet.isNumpyEnabled()。pip 安装了 PyBullet,如果系统上可用的话。目前,只有使用numpy加速的getCameraImage。

第 52 页

获取视觉形状数据

你可以使用getVisualShapeData来访问视觉形状信息。这可以用来连接你的渲染方法与PyBullet模拟,并在每个仿真步骤后手动同步世界变换。你也可以使用getMeshData,特别是对于可变形对象,以获取有关顶点位置的数据。

输入参数如下:

输出是一组视觉形状数据,每个视觉形状都采用如下格式:

物理模拟使用质心作为笛卡尔世界转换的参考,getBasePositionAndOrientation 和 getLinkState 中。如果你实现自己的渲染,你需要把局部视觉变换转换到世界空间中,利用质心的世界变换和 (逆) 当地惯性参照系。你可以通过 getLinkState 接口访问当地惯性参照系。

第 53 页

改变视觉形状,加载纹理

你可以使用 changeVisualShape 来改变形状的纹理、RGBA 颜色和其他属性。

载入纹理

从文件中加载纹理,并在加载成功时返回一个非负的纹理唯一标识符。此唯一标识符可用于 changeVisualShape 中。

碰撞检测查询

您可以查询上一个“stepSimulation”或“performCollisionDetection”中存在的接触点信息。要获取接触点,可以使用“getContactPoints” API。注意,“getContactPoints”不会重新计算任何接触点信息。

获取重叠对象,获取轴对齐的边界盒。

此查询将返回所有具有与给定轴对齐的边界框重叠的轴对齐边界框的对象的唯一标识符。注意,该查询是保守的,并且可能返回没有实际 AABB 重叠的额外对象。这是因为加速器中每个节点都包含了它的子树中的所有物体。

第 54 页

结构有一些启发式方法来稍微扩大 AABBS(额外的边距和沿着速度向量的挤压)。

getOverlappingObjects 将返回一个对象唯一标识符列表。

获取 AABB

你可以通过一个唯一标识符来查询一个轴对齐的边界盒(在世界空间中),并可选地传递一个链接索引。(如果你不传递链接索引,或者使用 -1 ,你会得到基座的 AAB )。

输入参数为

返回结构是一个包含世界空间坐标系下的vec3、aabbMin(x,y,z) 和aabbMax(x,y,z) 的列表。

参见 getAABB.py 示例。

获取接触点,获取最近距离

getContactPoints 接口返回在最近一次调用 stepSimulation 或 performCollisionDetection 后计算出的接触点。注意,如果在 stepSimulation 或 performCollisionDetection 调用之后更改了模拟状态,则 'getContactPoints' 将不会更新并且可能无效。其输入参数如下:

第 55 页

获取最近点

也可以独立于 步进模拟或碰撞检测来计算最近点。 这也让你能够计算具有任意分离距离的对象之间的最近点。 在此查询中,不会报告法向力。

第 56 页

getClosestPoints 返回与 getContactPoints 相同格式的最近点列表(但 此时 正交力总是为零)

rayTest, rayTestBatch

当有相交时,射线测试查询会返回以下信息:

射线测试批次

这与 rayTest 类似,但允许您提供一组射线以进行更快的执行。 rayFromPositions 的大小必须等于 rayToPositions 的大小。 即使没有相交,也可以为每个射线获得一个结果:您可以使用物体唯一标识字段来检查光线是否击中了任何东西:如果对象唯一标识符为 -1,则没有击中。 在这种情况下,“命中分数”为 1。 批量中的最大射线数

pybullet.MAX_RAY_INTERSECTION_BATCH_SIZE.

第 57 页

rayTestBatch 的输入参数为:

输出为输入射线的每个交点结果,与上述射线测试查询中的信息相同。请参阅 batchRayTest.py 示例了解如何使用它。

获取碰撞形状数据

你可以使用这个查询来查询现有身体基座和关节的碰撞几何类型和其他碰撞形状信息。它的工作原理与getVisualShapeData非常相似。

getCollisionShapeData 的输入参数如下:

第 58 页

返回值是一个列表,包含如下元素:

启用/禁用碰撞

默认情况下,不同的动态移动体之间启用碰撞检测。可以使用类似这样的标志启用同一身体链接之间的自碰撞:

loadURDF(参见loadURDF命令了解更多信息)中的 'URDF_USE_SELF_COLLISION' 标志。

您可以使用 setCollisionFilterGroupMask API 启用或禁用对象组之间的碰撞检测。

V-HACD

PyBullet 包含由 Khaled Mamou 实现的 体素层次近似分解 (vhacd)。它可以导入一个凹多边形 Wavefront.obj 文件,并导出一个新的 Wavefront obj 文件,其中包含凸分解部分。这可以用于在 PyBullet 中高效处理凹面移动几何图形。

对于 静态(非移动) 的凹多边形三角网格环境,您可以通过在URDF文件中使用标签标记为凹多边形 (),或通过创建碰撞形状并使用p.GEOM_FORCE_CONCAVE_TRIMESH标志。

第 59 页

示例用法:

以上内容的翻译是:

import pybullet as p

import pybullet_data as pd

import os

第 60 页

连接到 p.DIRECT

name_in = pd.getDataPath() + "duck.obj"

name_out = "duck_vhacd2.obj"

name_log = "log.txt"

p.vhacd (name_in, name_out, name_log)

设置碰撞过滤器组掩码

每个身体都是一个组的一部分。如果他们的组与掩码匹配,那么它就会与其他身体碰撞;反之亦然。下面的检查使用两个身体的组和掩码来执行。这取决于碰撞过滤器模式。

你可以对特定链接之间的碰撞检测进行更精细的控制。

使用 setCollisionFilterPair() 接口:您可以启用或禁用碰撞检测。

setCollisionFilterPair 将覆盖过滤器组/掩码和其他逻辑。

设置碰撞过滤器对

第 61 页

还有一个 插件API,可以让你自己编写碰撞过滤器实现,参见 collisionFilterPlugin 实现。

逆动力学,运动学

计算逆动力学( 2 )

calculateInverseDynamics 将根据给定的关节加速度,从指定的关节位置和速度开始计算所需的力。逆动力学使用递归牛顿欧拉算法 (RNEA) 进行计算。

calculateInverseDynamics 返回每个自由度的关节力列表。 注意,当涉及多 DOF(球形)关节时,calculateInverseDynamics 使用不同的代码路径,并且速度稍慢。 还请注意,calculateInverseDynamics 忽略了关节/链接阻尼,而前向动力学(在 stepSimulation 中)包括这些阻尼项。 因此,如果您想比较逆动力学和前向动力学,请确保使用 changeDynamics 通过线性阻尼和角阻尼设置这些阻尼项为零。

计算雅可比矩阵,质量矩阵

calculateJacobian 会计算链接上某一点的平移和旋转雅可比矩阵,例如 x_dot = J * q_dot。返回的雅可比矩阵根据 w 是否为 true 而略有不同

第 62 页

根关节是否为固定或浮动。如果是浮动的话,雅可比矩阵会包含对应于根关节的自由度列;如果固定的话,则只有与关节有关的列。函数调用采用完整的运动学状态描述,这是因为先要调用calculateInverseDynamics并从中提取所需的雅可比矩阵,因此也可以合理地传入零向量作为期望的关节速度和加速度。

calculateJacobian 返回:

计算质量矩阵

calculateMassMatrix 会根据关节位置计算一个刚体系统的惯性。复合刚体算法(CBRA)用于计算质量矩阵。

结果是一个dofCount * dofCount维的方块质量矩阵,以一个包含dofCount行的列表形式存储,每行都是一个包含dofCount个质量矩阵元素的列表。

注意,当使用多自由度(球形)关节时,calculateMassMatrix 将使用不同的代码路径,速度会慢一些。

第 63 页

反向运动学

您可以计算关节角度,使末端执行器达到给定的目标位置。在内部,Bullet 使用了改进版的Samuel Buss逆运动学库。目前只提供了带或不带空闲空间控制的阻尼最小二乘法,有一个末端执行器目标。您还可以选择性地指定末端执行器的目标方向。此外,还有一个选项可以使用空闲空间来指定关节限制和休息姿势。这个可选的空闲空间支持需要所有四个列表(lowerLimits、upperLimits、jointRanges、restPoses),否则会使用常规IK。参见Bullet/examples/pybullet/examples文件夹中的inverse_kinematics.py示例了解详情。

计算逆运动学(2)

计算逆运动学输入参数如下:

第 64 页

calculateInverseKinematics 返回一个每个自由度关节位置的列表,因此此列表的长度等于关节(忽略基座和固定关节)的自由度数。参见 Bullet/examples/pybullet/inverse_kinematics.py 示例。

默认情况下,IK 会优化解决方案,直到目标末端执行器与实际末端执行器之间的距离小于残差阈值(1e-4)或达到最大迭代次数。

计算逆运动学 2

与计算逆运动学类似,但它接受一个包含末端执行器索引及其目标位置(目前没有方向)的列表。

第 66 页

强化学习环境 gym

在“pip install pybullet”安装过程中,会安装一系列强化学习 (RL) Gym 环境。其中包括了 PyBullet 版本的 OpenAI Gym 环境,如蚂蚁、弹跳器、类人生物和步行者。还有一些适用于模拟以及真实机器人的环境,例如 Ghost Robotics Minitaur 四足机器人、麻省理工赛车和 KUKA 机械臂抓取环境。

pybullet、pybullet_envs、pybullet_data 和示例代码可在 https://github.com/bulletphysics/bullet3/tree/master/examples/pybullet/gym 中找到。

你可以使用深度强化学习算法(如DQN、PPO、TRPO和DDPG)训练环境。有多个预训练示例可供使用,你可以像这样欣赏它们:

安装pybullet,tensorflow 和 gym。

python -m pybullet_envs.examples.enjoy_TF_HumanoidBulletEnv_v0 2017may python -m pybullet_envs.examples.kukaGymEnvTest

环境与数据

在您运行 "sudo pip install pybullet" 之后,pybullet_envs 和 pybullet_data 就可用。导入 pybullet_envs 包会自动注册环境到 OpenAI Gym。

你可以使用以下Python语句来获取gym中Bullet环境的列表:python3 -c "exec('import pybullet_envs print(pybullet_envs.getList())')"

第 68 页

我们把 Roboschool 环境移植到了 PyBullet 中。Roboschool 环境比 MuJoCo Gym 环境更难。

第 69 页

还可以访问 pybullet_data 包中的数据,例如 URDF/SDF 机器人资产、Wavefront.OBJ 文件。下面是如何做到这一点的一个例子:

import pybullet

导入pybullet_data

datapath = pybullet_data.getDataPath()

pybullet.connect(pybullet。GUI)

pybullet.setAdditionalSearchPath(datapath)

pybullet.loadURDF("r2d2.urdf", [0, 0, 1])

第 70 页

或者,手动在 loadURDF/SDF 命令中追加数据路径到文件名。

Stable Baselines & ARS, ES,...

对于连续控制型 Gym 环境,如 HalfCheetah (HalfCheetahBulletEnv-v0)、Ant (AntBulletEnv_v0)、(Hopper) HopperBulletEnv_v0、CartPoleContinuousBulletEnv-v0,您可以使用 Stable Baselines。这是一个示例:

用 pip3 安装稳定的基础行为 -- 用户

pip3 安装 pybullet --user python3-m pybullet_envs.stable_baselines.train --algo sac --env HalfCheetahBulletEnv-v0

为了享受训练环境,请复制/重命名权重文件到

sac_HalfCheetahBulletEnv-v0.zip(去掉最佳部分)

python3 -m pybullet_envs.stable_baselines.enjoy --algo sac --env HalfCheetahBulletEnv-v0 --n-episodes 5

Stable Baselines Zoo 提供了预训练的 PyBullet 环境。

您还可以使用 Google Colab 笔记本中的 Stable Baselines 训练并享受 PyBullet 环境,参见此 Colab 示例训练 CartPole。

训练与享受:DQN、PPO、ES

对于诸如 KukaBulletEnv-v0 和 RacecarBulletEnv-v0 这样的离散 Gym 环境,您可以使用 OpenAI 基线 DQN 在离散动作空间中训练模型。提供了几个示例来演示如何在这些离散环境中进行训练和享受:

python -m pybullet_envs.baselines.train_pybullet_cartpole python -m pybullet_envs.baselines.train_pybullet_racecar

当模型提升时, OpenAI Baselines 会在指定的时间间隔内保存 .pkl 文件。 这个 .pkl 文件在 enjoy 脚本中使用:

python -m pybullet_envs.baselines.enjoy_pybullet_cartpole python -m pybullet_envs.baselines.enjoy_pybullet_racecar

第 71 页

PyBullet 还提供了一些预先训练好的模型,你可以直接拿来使用。这里列出了可以享受的预训练环境列表:

python -m pybullet_envs.examples.enjoy_TF_AntBulletEnv_v0_{2017}may

python-m pybullet_envs.examples.enjoy_TF_HalfCheetahBulletEnv_v0_2017may

python -m pybullet_envs.examples.enjoy_TF_AntBulletEnv_v0_{2017}may

python-m pybullet_envs.examples.enjoy_TF_HopperBulletEnv_v0_2017may

python -m pybullet_envs.examples.enjoy_TF_HumanoidBulletEnv_v0 2017may

python-m pybullet_envs.examples.enjoy_TF_InvertedDoublePendulumBulletEnv_v0_2017may

python-m pybullet_envs.examples.enjoy_TF_InvertedPendulumBulletEnv_v0_2017may

python-m pybullet_envs.examples.enjoy_TF_InvertedPendulumSwingupBulletEnv_v0_2017may

python -m pybullet_envs.examples.enjoy_TF_Walker2DBulletEnv_v0__2017may

使用TensorFlow & PyTorch 训练

你可以使用TensorFlow Agents中的PPO训练各种PyBullet环境。首先安装所需的Python包:pip install gym tensorflow agents pybullet ruamel.yaml

然后用于训练:

dir

可用的环境配置如下:

PyBullet 悬摆

双摆(双摆)

PyBullet 悬摆上推

PyBullet猎豹

PyBullet蚂蚁

PyBullet 赛车

pybullet_minitaur

你可以使用 TensorBoard 查看训练进度:

tensorboard --logdir=pendulum --port=2222

打开网络浏览器,访问 localhost:2222 页面。这是 TensorBoard 中关于摆锤训练的一个示例图表:

模拟/条件 3 的平均分数

第 72 页

训练后,您可以可视化训练好的模型,创建视频或使用物理服务器(python-m pybullet_envs/examples/runServer 或 物理服务器模式下的ExampleBrowser 或虚拟现实)进行可视化。如果您启动了本地 GUI 物理服务器,那么可视化器(bullet_client.py)会自动连接到它,并使用 OpenGL 硬件渲染来生成视频。否则,它将使用CPU tinyrenderer。要生成视频,请使用:

python -m pybullet_envs.agents.visualize_ppo --logdir=pendulum/xxxxx --outdir=pendulum_video

你可以用类似的方式训练和可视化迷你牛机器人:

python -m pybullet_envs.agents.train_ppo --config=pybullet_minitaur --logdir=pybullet_minitaur 这里有一个 MiniTaur 步态的例子视频:https://www.youtube.com/watch?v=tfqCHDoFHRQ

进化策略(ES)

David Ha (hardmaru) 在他的博客上发表了一篇关于如何使用进化策略训练 PyBullet 环境的文章,网址为:Evolving Stable Strategies | 大トロ

使用PyTorch PPO进行训练

我们将在下面添加一些如何开始使用PyTorch和pybullet的说明。同时,查看这个仓库:https://github.com/ikostrikov/pytorch-a2c-ppo-acktr

第 73 页

虚拟现实

参见vrBullet快速入门指南。

VR 物理服务器使用 OpenVR API 来支持 HTC Vive 和 Oculus Rift Touch 控制器。OpenVR 为 Windows 提供支持,Valve 正在开发 Linux 版本。

请参阅 <https://www.youtube.com/watch?v=VMJyZtHQL50>,观看使用 PyBullet 通过共享内存、UDP 或 TCP 连接完全控制的 Bullet 示例视频。

对于 Windows 上的虚拟现实,建议使用 Microsoft Visual Studio (MSVC) 编译 Bullet 物理引擎SDK。生成

运行“build_visual_studio_vr_pybullet_double.bat”脚本以生成 MSVC 项目文件。你可以自定义这个小脚本来指向 Python 等位置。确保切换到

MSVC 的“发布”配置,以及构建和运行

App_PhysicsServer_SharedMemory_VR*.exe。默认情况下,这个虚拟现实应用程序会呈现一个空的世界,展示跟踪器/控制器(如果有的话)。

获取VR 事件,设置 VR 相机状态

getVREvents 将返回一个 从上次以来发生变化 的VR设备事件列表。

调用getVREvents()。如果不提供设备类型过滤器,将只报告默认值

VR 设备控制器状态。您可以选择任何设备组合,包括

VR 设备控制器、头戴式显示装置 (HMD) 和通用跟踪器(例如HTC VIVE 便携式追踪器)。

注意,VR_DEVICE_HMD 和 VR_DEVICE_GENERIC_TRACKER 只报告位置和方向事件。getVREvents 具有以下参数:

输出参数如下:

第 74 页

请参阅 Bullet/examples/pybullet/examples/vrEvents.py 以查看虚拟现实绘图示例,以及 Bullet/examples/pybullet/examples/vrTracker.py 以跟踪头戴式显示器 (HMD) 和通用跟踪器。

设置 VR 相机状态

setVRCameraState 允许设置相机根变换偏移位置和方向。这允许控制虚拟世界中 VR 相机的位置。还可以让 VR 相机跟踪一个对象,比如车辆。

第 75 页

调试GUI、行、文本、参数

PyBullet 有一些功能来帮助调试、可视化和调整模拟。这个特性只有在存在一个三维视图窗口时才有用,比如图形用户界面模式,或者连接到一个单独的物理服务器(例如在“物理服务器”模式下的“Example Browser”,或带有 OpenGL GUI 的独立物理服务器)。

\

添加用户调试行,点,文本,参数

你可以通过指定三维起始点(from)和结束点(to)、颜色(red, green, blue)、线宽以及持续时间(以秒为单位),来添加一条三维线。addUserDebugLine 的参数有:

addUserDebugLine 将返回一个非负的唯一标识符,可以使用 removeUserDebugItem 移除该行。 (如果使用'replaceItemUniqueId',它将返回replaceItemUniqueId)。

第 76 页

添加用户调试点

你可以使用这种方法来可视化点云。 参考这个带有示例zip文件的拉取请求。

添加用户调试文本

你可以使用颜色和大小在特定位置添加一些 3D 文本。输入参数如下:

第 77 页

addUserDebugText 将返回一个非负的唯一标识符,使用 removeUserDebugItem 可以移除该行。参见 pybullet/examples/debugDrawItems.py

添加用户调试参数

addUserDebugParameter 可以让你添加自定义滑块和按钮来调整参数。它会返回一个唯一的 ID。这样就可以使用 来读取参数值。

readUserDebugParameter。addUserDebugParameter 的输入参数如下:

滑块的返回值是最新的参数读数。对于按钮,每次按下按钮时,用户调试参数的值都会增加 1。

以下是翻译结果:

p.addUserDebugParameter(“button”, 1, 0, 1)

第 78 页

p.addUserDebugParameter(“my_slider”, 3, 5, 4)

移除所有用户参数

这会移除所有滑块和按钮。

移除用户调试项/全部

添加用户调试语句的函数,如果成功,文本会返回一个非负的唯一标识符。您可以使用 removeUserDebugItem 方法通过这个唯一标识符移除调试项。参数如下:

移除所有用户调试项

这个API会移除所有调试项(文本、行等)。

设置调试对象颜色

内置的 OpenGL 可视化器具有线框调试渲染功能:按下 'w' 键来切换。 线框有一些默认颜色。 您可以使用 setDebugObjectColor 重写特定对象的颜色和链接。 输入参数如下:

第 79 页

添加用户数据(获取,同步,删除)

简而言之,添加、删除或查询用户数据,目前是任何链接体上的文本字符串。 参考 userData.py 示例了解如何使用它。 它会返回一个 userDataId。 请注意,您也可以在 URDF 文件中添加用户数据。

获取用户数据

getUserData 将接收由 addUserData 返回的 userDataId 所对应的用户数据。参考 userData.py 中的使用示例。

同步用户数据

syncUserData 将同步用户数据 (getUserData),以防多个客户端更改用户数据(addUserData 等)。

删除用户数据

removeUserData 将删除一个用户数据 id 对应的数据。

getUserDataId 和 getNumUserData

getNumUserData 将返回给定 bodyUniqueId 的用户数据条目数。

获取用户数据信息

getUserDataInfo方法获取用户数据的键和标识符,参数包括 userDataId、key、bodyUniqueId、linkIndex 和 visualShapeIndex。

第 80 页

配置调试可视化器

您可以配置内置的 OpenGL 可视化程序的一些设置,例如启用或禁用线框、阴影和 GUI 渲染。这很有用,因为某些笔记本电脑或桌面 GUI 与我们的 OpenGL 3 可视化程序存在性能问题。

以下是翻译结果:

pybullet.configureDebugVisualizer(pybullet.COV_ENABLE_WIREFRAME, 1)

获取/重置调试可视化器相机

警告:getDebugVisualizerCamera 的返回参数与resetDebugVisualizerCamera 不同。将在未来版本中修复(主要新版本)。

重置调试可视化器相机

你可以重置三维OpenGL调试可视化器相机距离(眼睛与相机目标位置之间)、相机俯仰角和相机朝向以及相机目标位置。

第 81 页

示例:pybullet.resetDebugVisualizerCamera( cameraDistance=3, cameraYaw=30, cameraPitch=52, cameraTargetPosition=[0,0,0])

获取调试可视化相机

你可以使用这个命令来获取相机的宽度、高度(像素)、视图矩阵和投影矩阵。输入参数是可选的 physicsClientId。输出信息如下:

第 82 页

键盘事件 获取 鼠标事件

你可以获取上次调用以来发生的键盘事件。

'getKeyboardEvents'。每个事件都有一个键码和状态。状态是一个位标志组合

键被按下,KEY_WAS_TRIGGERED 和 KEY_WAS_RELEASED。如果一个键正在

从“上”到“下”,您会收到KEY_IS_DOWN状态,以及

KEY_WAS_TRIGGERED 状态。如果按键被按下并释放,状态将是KEY_IS_DOWN 和 KEY_WAS_RELEASED。

一些特殊键被定义:B3G_F1 ... B3G_F12,B3G_LEFT_ARROW;

B3G 右箭头,B3G 上箭头,B3G 下箭头,B3G 页上箭头,

B3G PAGE DOWN,B3G PAGE END,B3G HOME,B3G DELETE,B3G INSERT,B3G ALT,B3G SHIFT,B3G CONTROL,B3G RETURN。

getKeyboardEvents() 的输入是可选的 physicsClientId:

输出为一个按键码'key' 和 键盘状态 'value' 的字典。

例如,

qKey = ord('q')

keys = p.getKeyboardEvents()

如果qKey在keys中且 keys[qKey] & p.KEY_WAS_TRIGGERED:break;

获取鼠标事件

与 getKeyboardEvents 类似,您可以使用 getMouseEvents 获取上次调用 getMouseEvents 以来发生的鼠标事件。所有鼠标移动事件都合并为一个单个鼠标移动事件,并带有最新的位置。此外,给定按钮的所有鼠标按钮事件都会被合并。如果按下并释放了一个按钮,则状态将是“KEY_WAS_TRIGGERED”。我们重用了 KEY_WAS_TRIGGERED/KEY_IS_DOWN/KEY_WAS_RELEASED 来表示鼠标按钮的状态。

输出为以下格式的鼠标事件列表:

第 83 页

参见 createVisualShape.py 以查看鼠标事件的示例,以选择/着色对象。

插件

PyBullet 允许您使用 C 或 C++ 编写插件以添加自定义功能。一些核心功能,如PD控制、渲染、gRPC 服务器、碰撞过滤和虚拟现实同步,都是作为插件编写的。大多数 PyBullet 的核心插件默认情况下都进行了静态链接,因此无需手动加载或卸载它们。

在 Linux 上,eglPlugin 是默认随 PyBullet 一起提供的插件示例。可以启用它以使用硬件OpenGL 3.x渲染而无需X11上下文,例如用于Google云平台上的云计算渲染。请参阅eglRenderTest.py 示例了解如何使用它。

PyBullet 还附带了一个文件 IO 插件,可以加载来自压缩文件的文件,并允许缓存文件。 参考 fileIOPlugin.py 示例了解如何使用它。

加载插件,执行插件命令

loadPlugin 将返回一个 插件唯一标识符 整数。 如果插件ID为负,则表示该插件未加载。 一旦插件被加载,你可以使用

执行插件命令:

第 84 页

卸载插件

你可以通过插件ID卸载一个插件。

插件 API 与 PyBullet 共享相同的底层 C API,并具有与 PyBullet 相同的功能。

你可以 浏览PyBullet插件的实现,以了解其可能性。

构建并安装 PyBullet

在 Windows、Mac OSX 和 Linux 上安装 PyBullet 有几种不同的方法。我们使用的是 Python 2.7 和 Python 3.5.2,但预期大多数 Python 2.x 和 Python 3.x 版本都可以工作。让 PyBullet 工作起来最简单的方法是使用 pip 或 python setup.py:

使用Python的pip

确保已安装 Python 和 pip,然后运行:

安装pybullet pip 安装 pybullet

您可能需要使用 sudo pip 安装 pybullet 或 pip install pybullet --user。

注意,如果你使用pip安装了PyBullet,那么安装C++ Bullet 物理SDK也是有益的:它包含数据文件、物理服务器和对PyBullet有用的工具。

您也可以在Bullet Physics SDK根目录中运行 'python setup.py build' 和 'python setup.py install' (从 http://github.com/bulletphysics/bullet3 下载SDK)。

参见 pybullet · PyPI

或者,你可以使用 premake(Windows)或cmake 从源代码安装 PyBullet:

使用 Premake 进行 Windows 开发

第 85 页

确保在 C:\Python-3.5.2 (或其他版本文件夹名称) 中安装了某个 Python 版本。

首先从github获取源代码,使用

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

点击 build_visual_studio_vr_pybullet_double.bat 并在 Visual Studio 中打开 0_Bullet3Solution.sln 项目,如有需要请转换项目。

切换到发布模式,并编译“pybullet”项目。

然后有几种在 Python 解释器中导入 PyBullet 的方法:

1)将 pybullet_vs2010.dll 重命名为 pybullet.pyd 并以 bullet/bin 作为当前工作目录启动 Python.exe 解释器。如果要进行调试,可选操作:将 bullet/bin/pybullet_vs2010_debug.dll 重命名为 pybullet_d.pyd 并启动 python_d.exe)。

2)将bullet/bin/pybullet_vs2010.dll重命名为pybullet.pyd,并使用命令提示符:set PYTHONPATH = c:\ develop \ bullet3 \ bin(用实际包含Bullet的位置替换)或通过Windows GUI创建此PYTHONPATH环境变量

3)创建管理员提示符(cmd.exe),并按照以下方式创建符号链接:cd c: \ python-3.5.2\ dlls

mklink pybullet.pyd c:\develop\bullet3\bin\pybullet_vs2010.dll

将 pybullet.pyd 链接到 c:\develop\bullet3\bin\pybullet_vs2010.dll。

然后运行python.exe导入pybullet应该就可以工作了。

在Linux和Mac OS X上使用cmake

注意,推荐的方式是使用 sudo pip install pybullet (或 pip3)。使用 CMake 或 Premake 或其他构建系统仅适用于了解自己在做什么的开发人员,并且通常不提供支持。

首先从github获取源代码,使用

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

1)下载并安装cmake

第 86 页

2)在 Bullet 根目录中运行 shell 脚本:

build_cmake_pybullet_double.sh

3)确保Python找到我们的pybullet.so模块:

export PYTHONPATH=/your_path_to_bullet/build_cmake/examples/pybullet

就这样。运行一个 Python 解释器并输入“import pybullet”以查看模块是否加载。如果可以,那么你可以玩Bullet/examples/pybullet 中的 Pybullet 脚本。

可能存在的 macOS 问题

如果您在 macOS 上导入 pybullet 时遇到任何问题,请确保使用的是正确的 Python 解释器,该解释器与-DPYTHON_INCLUDE_DIR 和 -DPYTHON_LIBRARY(使用 CMake)中设置的库匹配。 您可能安装了多个 Python 解释器,例如当您使用 Homebrew 时。 请参阅此评论以获取示例。

● 尝试使用 CFLAGS='-stdlib=libc++' pip install pybullet,参见这个 issue。

可能遇到的 Linux 问题

• 确保安装了 OpenGL。

• 当使用Anaconda作为Python发行版时,安装libgcc以便找到“GLIBCXX”(参见)。

如何解决“找不到 glibcxx-3.4.20”的错误?

● 如果使用Anaconda作为Python发行版,则cmake可能无法找到python库。 你可以手动添加它们,方法是在文件../build_cmake/CMakeCache.txt中更改以下行:

'PYTHON_LIBRARY': '/usr/lib/python2.7/config-x86_64-linux-gnu/libpython2.7.so'

所以,

没有OpenGL 3 的 GPU 或 虚拟机

● 默认情况下,PyBullet 使用 OpenGL 3。某些远程桌面环境和 GPU 不支持 OpenGL 3,导致屏幕变灰或崩溃。您可以使用 --opengl2 标志降级到 OpenGL 2。这并不完全受支持,但它给您提供了一种查看场景的方法:

• 连接到 PyBullet(带有 GUI)并使用 --opengl2 选项。

● 或者,您可以在远程机器上运行物理服务器,使用 UDP 或 TCP 桥接,并通过 UDP 虚拟隧道从本地笔记本电脑连接到远程服务器。(todo: 详细说明步骤)

第 87 页

支持、提示、引用

问题:我们去哪里寻求帮助并报告问题?

答案:在Real-Time Physics Simulation Forum - Index page上有一个讨论论坛,在GitHub - bulletphysics/bullet3: Bullet Physics SDK: real-time collision detection and multi-physics simulation for VR, games, visual effects, robotics, machine learning etc.上有一个问题追踪器。

问题:我们如何在学术论文中引用PyBullet? 回答:@MISC { coumans2020 ,

作者:Erwin Coumans 和 Yunfei Bai,

标题:{PyBullet,用于游戏、机器人和机器学习的物理模拟 Python 模块}

发表于{\url{http://pybullet.org}},

年份= { 2016 - 2023 }

问题:PyBullet 可以在 Google Colab 中使用吗?

回答:是的,我们提供可以在 Colab 中使用的预编译的 manylinux 轮子。

GPY 渲染也使用了 EGL。 在这里查看一个 Colab 示例。

问题:Bullet 2.x 和 Bullet 3 的 OpenCL 实现会发生什么?

答案:PyBullet 是一个包装了 Bullet 的 C 接口。我们会把 Bullet 3 的 OpenCL GPU 接口(以及未来的 Bullet 4.x 接口)放在这个 C 接口后面。所以如果你使用的是 PyBullet 或者 C 接口,那么你的未来就有了保障。不要把它和 Bullet 2.x 的 C++ 接口搞混了。

问题:我应该使用扭矩/力控制还是速度/位置模式?

一般来说,最好从位置或速度控制开始。

要使力矩控制可靠地工作,需要付出更多的努力。

问题:物体的速度似乎比预期的小。PyBullet是否应用了默认阻尼?此外,速度也没有超过100个单位。

答案:是的,PyBullet 会对角速度和线速度应用一些阻尼来提高稳定性。你可以使用 'changeDynamics' 命令通过设置 linearDamping=0 和 angularDamping=0 来修改/禁用这种阻尼。

为了稳定,最大线性/角速度被限制为100个单位。

问题:如何只对机器人的一部分(例如手臂)关闭重力?回答:

目前这并没有暴露出来,所以你需要关闭重力。

对所有物体施加加速,手动给需要的物体施加重力。

或者你可以主动计算重力补偿力,就像在真实情况下一样。

机器人。由于弹丸具有完整的约束系统,因此可以轻松计算

那些反重力力量:你可以运行一个模拟(PyBullet让你可以)

第 88 页

连接到多个物理服务器)并使机器人处于重力下,设置关节位置控制以保持所需的位置,并收集“反重力”力。 然后在主模拟中应用这些力。

问题:如何缩放对象?

答案:你可以使用全局缩放因子值作为可选参数来加载urdf和sdf。否则,大多数文件格式(如urdf和sdf)中的视觉形状和碰撞形状的缩放都是其中的一部分。目前无法重新缩放对象。

问题:我如何在我的模型中获得纹理?

答案:你可以使用 Wavefront .obj 文件格式。它支持材质文件(.mtl)。在 Bullet / data 目录中有许多使用纹理的例子。您可以使用“更改纹理”API 更改现有带纹理对象的纹理。

问题:PyBullet 支持哪些纹理文件格式?

答案:Bullet使用stb_image加载纹理文件,可以加载PNG、JPG、TGA、GIF等格式。详情请参见stb_image.h。

问题:我如何提高碰撞检测的性能和稳定性?回答:优化的方法有很多,例如:

形状类型

1)选择一个或多个基本碰撞形状类型,如盒子、球体、圆柱体来近似物体,而不是使用凸多边形或凹多边形三角网格。

2)如果你真的需要使用三角网格,可以使用层次近似凸分解(Hierarchical Approximate Convex Decomposition,HACD)创建一个凸分解。test_hacd 工具可以将 OBJ 文件中的凸三角形网格转换为多个凸壳对象的新 OBJ 文件。参见 Bullet/data/teddy_vhacd.urdf 中指向的内容。

Bullet/data/teddy2_VHACD_CHs.obj 或者指向duck_vhacd.obj 的duck_vhacd.urdf。

3)减少三角形网格中的顶点数。例如,Blender 3D 中有一个非常棒的网格简化修改器,它允许您交互式地查看网格简化结果。

4)对于滚动摩擦使用较小的正值(例如 0.01),并为球体和胶囊等圆形物体以及机器人夹爪使用旋转摩擦。在 节点内的<rolling_friction> 和<spinning_friction> 节点中使用这些值。参见 Bullet/data/sphere2.urdf 示例。

5)使用少量的通过在URDF XML节点中使用来为轮子施加刚度。例如参见Bullet / data / husky / husky.urdf 车辆。

6)使用Bullet的双精度构建,这在接触稳定性方面以及碰撞准确性方面都很好。选择一些好的约束求解器设置和时间步长。

7) 将物理模拟与图形分离。 PyBullet 已经为 GUI 和各种物理服务器做到了这一点:OpenGL 图形可视化在自己的线程中运行,独立于物理模拟。

第 89 页

问题:摩擦处理有哪些选择?

答案:默认情况下,Bullet 和 PyBullet 使用库仑摩擦模型来实现精确的隐式锥形摩擦。此外,您还可以通过在节点内添加一个<rolling_friction>和一个<spinning_friction>节点来启用滚动和旋转摩擦,参见 Bullet/data/sphere2.urdf 示例。您可以使用锥形摩擦替代金字塔近似。

问题:是什么常数或阈值在Bullet内部,使高速成为不可能?回答:默认情况下,Bullet依赖于离散碰撞检测结合穿透恢复。仅仅依靠离散碰撞检测意味着物体在一个时间步长内不能超过其自身半径的速度。PyBullet使用1/240作为默认的时间步长。大于1/60的时间步长可能会因为深度穿透、数值积分等原因导致不稳定。Bullet有一个连续碰撞检测选项来捕捉一个时间步长内移动速度超过自身半径的对象之间的碰撞。不幸的是,这种连续碰撞检测可以引入自己的问题(性能和非物理响应、缺乏恢复力),因此这个实验功能不是默认启用的。查看实验性CCDSphereRadius.py示例以了解如何启用它。

问题:有些 API 没有文档。通常这意味着 (1) 我们还没有更新快速入门指南,或者 (2) 这个功能太实验性以至于无法进行文档化。如果你真的想知道某个特定的未文档化的 API 的信息,可以在这个追踪器中提交一个 Issue。

全部文档

提问

enter发送 / shift+enter换行

服务生成的所有内容均由人工智能模型生成,其生成内容的准确性和完整性无法保证,不代表我们的态度或观点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值