☰

教程 5:复合实体与物理属性(15 分钟)

本教程的目标是通过创建具有多个包围体的实体来更深入地探索物理仿真:一个由两个球体和一个圆柱体组成的哑铃。预期结果如此图所示。

tutorial_dumbbell.png

关于复合实体教程结束时的预期结果。

新仿真

动手实践 #1:以上一个教程的结果为基础,使用菜单 File / Save World As... 创建一个名为 compound_solid.wbt 的新仿真。

复合实体

通过组合多个 [Shape(https://cyberbotics.com/doc/reference/shape) 节点,可以构建比以往所见更复杂的 [Solid(https://cyberbotics.com/doc/reference/solid) 节点。 事实上,[Solid(https://cyberbotics.com/doc/reference/solid) 的物理属性和图形属性都可以由多个 [Shape(https://cyberbotics.com/doc/reference/shape) 节点组成。 此外,每个 [Shape(https://cyberbotics.com/doc/reference/shape) 节点都可以放置在一个 [Pose(https://cyberbotics.com/doc/reference/pose) 节点中,以改变其相对位置和朝向。 [Group(https://cyberbotics.com/doc/reference/group) 节点也可用于将多个子节点组合在一起。

我们要实现一个由手柄([Cylinder(https://cyberbotics.com/doc/reference/cylinder))和位于手柄两端的两个配重([Sphere(https://cyberbotics.com/doc/reference/sphere))组成的哑铃。 此图展示了实现该哑铃所需的 [Solid(https://cyberbotics.com/doc/reference/solid) 节点及其子节点。

动手实践 #2:按照此图创建哑铃。 先创建手柄,不要将其放置在 [Pose(https://cyberbotics.com/doc/reference/pose) 节点中(因此手柄的轴将与实体的 z 轴方向一致)。 手柄的长度应为 0.1 m,半径应为 0.01 m。 配重的半径应为 0.03 m,细分级数(subdivision)应为 2。 借助配重所在 [Pose(https://cyberbotics.com/doc/reference/pose) 节点的 translation 字段,可以将配重移动到手柄的两端。

节点关系图
graph TD
  Solid[Solid] -->|physics| Physics[Physics]
  Solid -->|boundingObject| USEG0[USE G0]
  Solid -->|children| Group[DEF G0 Group]
    Group -->|children| Shape1[Shape]
      Shape1 -->|geometry| Cylinder[Cylinder]
    Group -->|children| Pose1[Pose]
      Pose1 -->|children| Shape2[Shape]
        Shape2 -->|geometry| Sphere1[Sphere]
    Group -->|children| Pose2[Pose]
      Pose2 -->|children| Shape3[Shape]
        Shape3 -->|geometry| Sphere2[Sphere]
    USEG0 -.- Group

  class Solid highlightedNode;
  class USEG0,Group secondaryNode;
由多个经过变换的几何体构成的复合实体的子节点示意图。

物理属性

本小节的目标是学习如何为 [Solid(https://cyberbotics.com/doc/reference/solid) 节点设置一些简单的物理属性。 [Physics(https://cyberbotics.com/doc/reference/physics) 节点包含与当前刚体([Solid(https://cyberbotics.com/doc/reference/solid))物理特性相关的字段。

[Solid(https://cyberbotics.com/doc/reference/solid) 节点的质量由其 density(密度)或 mass(质量)字段给出。 这两个字段一次只能指定其中一个(另一个应设置为 -1)。 当指定 mass 时,它定义实体的总质量(单位为 [kg])。 当指定 density 时,其值(单位为 [kg/m3])会乘以包围体的体积,所得乘积即为实体的总质量。 1000 [kg/m³] 的密度对应水的密度(默认值)。

动手实践 #3:将哑铃的质量设置为 2 [kg]。 密度不使用,应设置为 -1。

默认情况下,[Solid(https://cyberbotics.com/doc/reference/solid) 节点的质心位于其原点(由实体的 translation 字段定义)。 可以使用 [Physics(https://cyberbotics.com/doc/reference/physics) 节点的 centerOfMass 字段修改质心。 质心是相对于 [Solid(https://cyberbotics.com/doc/reference/solid) 原点指定的。

动手实践 #4:假设其中一个配重比另一个更重。 将哑铃的质心沿 z 轴移动 0.01 [m]。

请注意,当选中该实体时,质心在 3D 视图中由一个坐标系表示,该坐标系比表示实体中心的坐标系颜色更深。

rotation 字段

[Pose(https://cyberbotics.com/doc/reference/pose) 节点的 rotation 字段使用欧拉轴与角表示法来确定该节点(及其子节点)的旋转。 欧拉轴与角旋转由四个分量定义。 前三个分量是定义旋转轴的单位向量。 第四个分量定义绕该轴的旋转角度(单位为 [rad])。

旋转方向遵循右手定则。

动手实践 #5:修改哑铃 [Solid(https://cyberbotics.com/doc/reference/solid) 节点的 rotation 字段,使手柄的轴(z 轴)与地面平行。 单位轴(0, 1, 0)加上 π/2(约 1.5708)的旋转角是一种可行的解法。

如何选择包围体?

如前所述,减少包围体的数量可以提高仿真速度。 然而,仔细选择包围体的基元类型对于提高仿真速度也至关重要。

使用 [Sphere(https://cyberbotics.com/doc/reference/sphere)、[Box(https://cyberbotics.com/doc/reference/box)、[Capsule(https://cyberbotics.com/doc/reference/capsule) 和 [Cylinder(https://cyberbotics.com/doc/reference/cylinder) 节点的组合来定义物体是非常高效的。 一般而言,这些基元的效率可以这样排序:[Sphere(https://cyberbotics.com/doc/reference/sphere) > [Box(https://cyberbotics.com/doc/reference/box) > [Capsule(https://cyberbotics.com/doc/reference/capsule) > [Cylinder(https://cyberbotics.com/doc/reference/cylinder),其中 [Sphere(https://cyberbotics.com/doc/reference/sphere) 效率最高。 但在常规使用中,这种差异可以忽略不计。

[IndexedFaceSet(https://cyberbotics.com/doc/reference/indexedfaceset) 几何基元也可以用作包围体。 但该基元的效率低于上面列出的其他基元。 此外,它的行为有时存在缺陷。 因此,当可以通过组合其他基元实现另一种方案时,我们不建议使用 [IndexedFaceSet(https://cyberbotics.com/doc/reference/indexedfaceset)。

地面可以使用 [Plane(https://cyberbotics.com/doc/reference/plane) 或 [ElevationGrid(https://cyberbotics.com/doc/reference/elevationgrid) 基元来定义。 [Plane(https://cyberbotics.com/doc/reference/plane) 节点比 [ElevationGrid(https://cyberbotics.com/doc/reference/elevationgrid) 节点高效得多,但它只能用于建模平坦地形,而 [ElevationGrid(https://cyberbotics.com/doc/reference/elevationgrid) 可以用于建模起伏地形。

接触

当两个实体发生碰撞时,会在碰撞点创建接触。 [ContactProperties(https://cyberbotics.com/doc/reference/contactproperties) 节点可用于指定期望的接触行为(例如两个实体之间的摩擦)。

每个实体都属于一个由 contactMaterial 字段引用的材料类别(默认为 default)。 [WorldInfo(https://cyberbotics.com/doc/reference/worldinfo) 节点有一个 contactProperties 字段,用于存储一个 [ContactProperties(https://cyberbotics.com/doc/reference/contactproperties) 节点列表。 这些节点允许定义两类 [Solid(https://cyberbotics.com/doc/reference/solid) 之间的接触属性。

现在我们想要修改哑铃与环境中的其他实体之间的摩擦模型。

动手实践 #6:将哑铃的 contactMaterial 字段设置为 "dumbbell"。 在 [WorldInfo(https://cyberbotics.com/doc/reference/worldinfo) 节点中,在 default 和 dumbbell 两个类别之间添加一个 [ContactProperties(https://cyberbotics.com/doc/reference/contactproperties) 节点。 尝试将 coulombFriction 字段设置为 0,并注意哑铃在地面上会滑动(而不是滚动),因为不再施加摩擦力。

basicTimeStep、ERP 与 CFM

物理仿真中最关键的参数存储在 [WorldInfo(https://cyberbotics.com/doc/reference/worldinfo) 节点的 basicTimeStep、ERP 和 CFM 字段中。

basicTimeStep 字段决定一个物理步的时长(单位为 [ms])。 该值越大,仿真速度越快,但仿真精度越低。 对于 Webots 的常规使用,我们建议取值在 8 到 16 之间。

ERP 和 CFM 字段的行为较难解释。 这两个值被物理引擎直接用于确定约束的求解方式。 其默认值针对 Webots 的常规使用已定义得很好。 要完全理解它们的用途,我们建议阅读[参考手册(https://cyberbotics.com/doc/reference/worldinfo)以及 ODE(Webots 使用的物理引擎)的文档。

次要物理参数

还有一些在 Webots 常规使用中不太常用的物理参数,例如 [Physics(https://cyberbotics.com/doc/reference/physics)、[WorldInfo(https://cyberbotics.com/doc/reference/worldinfo) 和 [ContactProperties(https://cyberbotics.com/doc/reference/contactproperties) 节点的某些字段。

动手实践 #7:查找如何为所有对象添加线性阻尼、如何使用惯性矩阵,以及如何使用 physicsDisableTime 属性。

解答:世界文件

要将你的世界与解答进行对比,请打开你的文件,找到在[教程 1(tutorial-1-your-first-simulation-in-webots.html)中创建的名为 "my_first_simulation" 的文件夹,然后进入 "worlds" 文件夹,用文本编辑器打开正确的那个世界文件。 本解答与其他解答一样位于解答目录中。

结论

你现在已经能够构建各种各样的实体,包括由多个刚体组成的实体。 你知道如果一个 Geometry 节点被包含在 [Pose(https://cyberbotics.com/doc/reference/pose) 节点中,它就可以被移动和旋转。 你已了解所有可用于设计稳健仿真的物理参数。 下一步将是创建你自己的机器人。

你可以通过创建常见物体(例如一张桌子)来检验自己的技能。