其他相关教程
介绍
在本教程中,我们将学习如何向我们的世界添加演员(actors) 以及如何创建脚本动画。你可以在这里找到本教程的最终仿真世界文件。
动画在我们希望实体遵循模拟中预定义的路径而不受物理影响时非常有用。这意味着它们不会因重力而掉落或与其他物体碰撞。然而,它们将具有可以被 RGB 摄像头看到的 3D 可视化,以及可以被基于 GPU 的传感器检测到的 3D 网格。该教程解释了如何创建不与仿真的其余部分交互的开环轨迹。
演员
在 Gazebo Sim 中,动画模型被称为演员。
有两种类型的动画,可以单独使用或结合使用:
-
骨架动画,即一个模型中链接之间的相对运动:
-
轨迹动画,它将所有演员的链接作为一个整体沿着轨迹在世界各地移动:
-
结合使用,以实现世界上移动的骨架动画:
演员具有以下属性:
- 它们不受任何力的影响,无论是重力、接触还是其他任何力演员支持从 COLLADA (.dae) 和 BVH (.bvh) 文件导入的骨架动画。
- 演员可以直接在 SDF 中编写轨迹脚本。
你可以在这里查看<actor>
SDF 元素的完整规范。
骨架
Gazebo Sim 支持两种不同的骨架动画文件格式:COLLADA (.dae) 和 Biovision Hierarchy (.bvh)。
打开任何世界,例如 empty.sdf 世界,并添加一个名为 actor_walking 的演员,如下所示:
<actor name="actor_walking">
<skin>
<filename>https://fuel.gazebosim.org/1.0/Mingfei/models/actor/tip/files/meshes/walk.dae</filename>
<scale>1.0</scale>
</skin>
<animation name="walk">
<filename>https://fuel.gazebosim.org/1.0/Mingfei/models/actor/tip/files/meshes/walk.dae</filename>
<interpolate_x>true</interpolate_x>
</animation>
</actor>
皮肤
在<skin>
标签中,我们刚刚加载了一个 COLLADA 文件 walk.dae,它指定了我们的演员的外观。当在<skin>
标签内使用 COLLADA 文件时,将加载其动画。<scale>
缩放皮肤的大小。
动画
在<animation>
标签中,我们使用<filename>
标签指定演员的移动方式。<interpolate_x>
用于在跟随轨迹的同时在路点之间插值动画。将其设置为 true 可以实现更逼真、更流畅的动画效果。只要骨骼兼容,我们就可以将不同的皮肤与不同的动画结合起来。现在运行世界,我们应该可以看到模型在移动。
注意: 你可以在 Gazebo Fuel 上找到许多演员和模型。
脚本轨迹
这是演员的高级动画,它包括在特定时间指定要达到的一系列姿势。Gazebo Sim 负责在它们之间插值运动,以使运动流畅。
在 X 轴上有位移的动画,如 walk.dae,将在跟随轨迹时对骨架进行动画处理。但是对于那些没有的动画,比如 talk_b.dae,如果有轨迹,它们的骨架就不会移动。
我们可以让我们的演员永远跟随指定的轨迹,并在世界加载后立即开始播放,如下所示:
<script>
<loop>true</loop>
<delay_start>0.000000</delay_start>
<auto_start>true</auto_start>
脚本在<actor>
和</actor>
标签之间定义。
在<script>
标签内部,提供了以下参数:
- loop:将此设置为 true,以循环重复脚本。为了实现流畅的连续运动,请确保最后一个航点与第一个航点匹配,就像我们将要做的那样。
- delay_start:这是等待开始脚本的时间(以秒为单位)。如果在循环中运行,每次循环开始前都会等待这个时间。
- auto_start:如果设置为 true,则动画应在模拟开始播放时立即开始。如果动画只应在由插件触发时开始播放,将此设置为 false 很有用。
让我们将轨迹定义为一系列航点:
<trajectory id="0" type="walk" tension="0.6">
<waypoint>
<time>0</time>
<pose>0 0 1.0 0 0 0</pose>
</waypoint>
<waypoint>
<time>2</time>
<pose>2.0 0 1.0 0 0 0</pose>
</waypoint>
<waypoint>
<time>2.5</time>
<pose>2 0 1.0 0 0 1.57</pose>
</waypoint>
<waypoint>
<time>4</time>
<pose>2 2 1.0 0 0 1.57</pose>
</waypoint>
<waypoint>
<time>4.5</time>
<pose>2 2 1.0 0 0 3.142</pose>
</waypoint>
<waypoint>
<time>6</time>
<pose>0 2 1 0 0 3.142</pose>
</waypoint>
<waypoint>
<time>6.5</time>
<pose>0 2 1 0 0 -1.57</pose>
</waypoint>
<waypoint>
<time>8</time>
<pose>0 0 1.0 0 0 -1.57</pose>
</waypoint>
<waypoint>
<time>8.5</time>
<pose>0 0 1.0 0 0 0</pose>
</waypoint>
</trajectory>
</script>
在<trajectory>
标签内,我们定义了一系列航点,演员将跟随这些航点。<trajectory>
有三个属性:id、type 和 tension。type 应与<animation>
标签的 name 属性中指定的值相同。因此,在这种情况下,它被指定为 walk。tension 参数用于控制轨迹与给定航点的贴合程度。默认的 tension 值为零,相当于 Catmull-Rom 样条,这可能导致动画越过航点。tension 值为 1 将导致动画贴合航点。tension 值应在 0 到 1 之间。
在轨迹标签下,我们定义了以下内容:
- waypoint:轨迹中可以有任意数量的航点。每个航点由一个时间和一个姿势组成:
- time:从脚本开始时计算的到达姿势的时间(以秒为单位)。
- pose:相对于初始演员姿势应到达的姿势。
运行仿真世界,我们应该看到我们的演员按照航点在一个正方形内移动。
注意:
- 定义航点的顺序并不重要,它们将按照给定的时间跟随。
- 整个轨迹是平滑的。这意味着你将得到流畅的运动,但航点中包含的确切姿势可能无法到达。
现在轮到你了!尝试不同的轨迹描述。