ROS2与Gazebo11入门教程-并行物理仿真(Parallel physics)
说明:
- 介绍并行物理仿真(Parallel physics)
概述
仿真机器人的复杂性,环境的空间大小以及传感器仿真的逼真度,这些都在决定实时或近实时约束条件下可以仿真什么内容时起重要作用。
Gazebo物理更新循环是CPU周期的主要消耗者之一。
在解算表示这些物理约束的基本数学问题的解算算法速度有限的条件下,物理引擎的并行化(目标在于运行现实中的复杂机器人和环境)是帮助提高性能的主要方向
并行策略
已经实现了物理引擎并行化的两种策略:孤岛(island)线程和位置误差校正(position error correction)线程。
有关这两种策略的结果和分析的更多详细信息,请参阅Gazebo网页上的并行物理仿真报告。
可以用以下SDFormat参数来启用这两个线程:
island_threads参数:用于孤岛线程的整数线程数
thread_position_correction参数:用于打开ODE快步位置误差校正线程的标志
孤岛线程
第一种策略试图对非交互实体的仿真进行并行计算。如果仿真实体通过铰接式关节(例如旋转关节或万向关节)连接或通过接触连接,则这些仿真实体正在进行交互。
交互实体组被聚类成“孤岛”,这些孤岛在数学上彼此相互分离。
因此,每个孤岛可以并行仿真。每完成一个仿真步骤后,就重新对孤岛的聚类进行计算。
位置误差校正线程
第二种策略试图加快“快步(QuickStep)”解算器解算孤岛内约束算法的速度。
ODE 快步(QuickStep)解算器是Gazebo的默认解算器,用于解算线性互补问题(LCP)带来的约束。
作为一个迭代的、固定时间步长的解算器,它容易发生位置误差,如物体的互穿。
为了校正这些误差,会计算出一个脉冲,该脉冲施加到互穿物体上以将它们推开从而相互分离。
这种位置校正方法会将人为能量添加到系统中。为了校正这种额外的能量,需要解算两个方程。
误差校正LCP用于校正物体位置,同时在无互穿误差校正的情况下对速度进行更新。
由于这两个方程彼此之间具有独立性,它们可以并行解算,因此可以同时使用两个线程进行计算,这就构成了第二种并行计算策略。
示例
- 下面这个代码段说明了如何使用具有一个孤岛线程但无位置校正线程的ode对物理引擎进行配置。
<physics type="ode" name="unthrottled1">
<real_time_update_rate>0.0</real_time_update_rate>
<ode>
<solver>
<thread_position_correction>0</thread_position_correction>
<island_threads>1</island_threads>
</solver>
</ode>
</physics>
- 而下面这个代码段则说明了如何使用具有3个孤岛线程和1个位置校正线程的ode对物理引擎进行配置。
<physics type="ode" name="split_unthrottled3">
<real_time_update_rate>0.0</real_time_update_rate>
<ode>
<solver>
<thread_position_correction>1</thread_position_correction>
<island_threads>3</island_threads>
</solver>
</ode>
</physics>
指派给physics标签的名称(name)使得我们可以在运行时使用命令gz physics -o <physics标签名称>(例如:gz physics -o unthrottled1)来更改物理引擎
请访问参阅“管理物理配置(Manage physics profiles)”教程,以获取有关Gazebo物理参数的更多详细信息。这些参数会影响物理仿真的性能、准确性和通常行为。
物理预设管理器界面提供了一种方法以在一组物理参数之间轻松切换并将这些参数保存到SDF中
运行代码
Gazebo目前在内循环的多个部分配备了高分辨率诊断计时器。计时器分辨率取决于所使用的硬件,在我们的测试机器上约为100ns。为了防止在正常使用期间性能下降,除非在编译过程中定义了ENABLE_DIAGNOSTICS标志,否则该计时器会被禁用。
对于每个仿真步骤,流逝的时间都会被测量,并被用于递增地计算以下统计值:每个诊断计时器的平均值、最小值、最大值和方差。这些统计值是使用math::SignalStats类进行计算的。
这会将诊断计时数据输出到~/.gazebo/diagnostics目录中。
可以使用以下命令带ENABLE_DIAGNOSTICS标志编译Gazebo:
# clone gazebo9
git clone https://github.com/osrf/gazebo -b gazebo9
# or clone gazebo 11
git clone https://github.com/osrf/gazebo -b gazebo11
cd gazebo
mkdir build
cd build
cmake .. -DENABLE_DIAGNOSTICS=1
make
sudo make install
测试场景
本节教程中介绍的并行化策略的有效性取决于所仿真的场景。 例如,孤岛线程策略可以并行仿真多个非交互机器人,而位置误差校正策略可以并行仿真单个机器人。以下测试场景会改变仿真实体的数量和复杂性,以说明每种并行化策略的性能
revolute_joint_test.world场景:在Gazebo的自动测试系统中使用了revolute_joint_test.world世界文件。该世界文件包含排列成一个圆圈的8个“带底座双摆锤”模型实例。该模型包括一个与地面接触的底座,该底座通过旋转关节连接到两个链接。这些模型排列紧密,但彼此之间并不接触。这个仿真场景包含接触、关节约束和多个孤岛。
- pr2.world场景:世界文件pr2.world包含位于平坦地面上的一个PR2机器人。没有其他可与该机器人交互的物体。PR2是一个具有48个刚体和58个铰接式关节的复杂机器人。这个仿真场景包含接触和关节约束,但只有一个孤岛。
- dual_pr2.world场景:世界文件dual_pr2.world包含位于平坦地面上的两个PR2机器人。这两个机器人彼此之间并不进行交互。此场景与pr2.world场景相似,但包含两个孤岛,从而可以用复杂机器人对每种并行化策略的效果进行比较
在revolute_joint_test.world仿真世界中的测试结果
对于这些测试场景,由于要跟踪实时因子real_time_factor值的改善情况,Gazebo会尽可能快地运行。可以用11.9.3.4小节中介绍的一些脚本在本地运行这些测试场景。这些脚本会订阅话题/gazebo/default/diagnostics,并在一个csv文件中记录实时因子real_time_factor值。
首先,分别用0个线程(控件)和1-6个线程对revolute_joint_test.world仿真世界的孤岛线程效果进行分析。对于1到4个线程,性能是逐步提高的,但是对于5、6和7个线程,性能却都停留在同一个点上,这表明存在一个临界线程数,超过该线程数后再添加更多线程也不会继续改善性能。对于其他仿真世界,这个临界线程数可能会不相同。该临界线程数取决于仿真世界及其中的模型。
- 当添加位置误差校正线程时,可以看到当线程多于2个时性能会提高。如您所见,只需增加2个线程,实时因子就会增大2倍。可以添加更多的线程,但是如上一个示例所示的那样,存在一个临界线程数,超过该线程数后再添加更多的线程并不能帮助提高性能。
- 可以在本地运行其他两个示例,用一个PR机器人和两个PR机器人来查看这些参数的效果。
运行一些实验
为了快速了解Gazebo中并行化的工作原理,我们将会运行一些实验。要更深入地了解这些实验,请参阅Gazebo并行物理仿真报告。
下面的实验结果对实时因子进行了测量,这是对Gazebo并行物理仿真报告中各个测试的一种简化,但是,如果是从软件包中安装Gazebo的,则这是另一种检测这些参数性能的方法(精确性更低)。
如上文所述,如果使用cmake标志-DENABLE_DIAGNOSTICS从源代码编译Gazebo,则只能访问诊断工具。
要运行实验,请执行以下命令:
# to run the revolute joint test
wget https://raw.githubusercontent.com/osrf/gazebo/diagnostics_scpeters/test/worlds/revolute_joint_test.world
gazebo --verbose -o unthrottled0 revolute_joint_test.world
# to run a simulation with a pr2
wget https://raw.githubusercontent.com/osrf/gazebo/diagnostics_scpeters/worlds/pr2.world
gazebo --verbose -o unthrottled0 pr2.world
# to run a simulation with two pr2
https://raw.githubusercontent.com/osrf/gazebo/diagnostics_scpeters/worlds/dual_pr2.world
gazebo --verbose -o unthrottled0 dual\_pr2.world
- 然后可以在另一个终端中使用以下命令更改运行中的物理仿真:
gz physics -o unthrottled0
# Simulate with island threading:
gz physics -o unthrottled1
# Simulate with island threading:
gz physics -o unthrottled2
...
# Simulate with threaded position error correction:
gz physics -o split_unthrottled0
# Simulate with both types of threading
gz physics -o split_unthrottled1
gz physics -o split_unthrottled2
...
其它资源
下面提供了一些可以运行相关实验的脚本以跟踪实时因子real_time_factor值的变化情况。
新建一个目录并进入该目录,命令为:
mkdir /tmp/gazebo_parallel
cd /tmp/gazebo_parallel
- 摆锤(Pendulums):
wget https://raw.githubusercontent.com/osrf/gazebo_tutorials/master/parallel/files/run_pendulum_tests.bash
bash run_pendulums_test.bash
PR2:
wget https://raw.githubusercontent.com/osrf/gazebo_tutorials/master/parallel/files/run_pr2_tests.bash
bash run_pr2_test.bash
Dual PR2:
wget https://raw.githubusercontent.com/osrf/gazebo_tutorials/master/parallel/files/run_dual_pr2_tests.bash
bash run_dual_pr2_test.bash
可视化数据:
- 要可视化数据,您的系统需要一些依赖项,包括:Python和这3个依赖包(matplotlib,pandas和numpy)。
pip install -U matplotlib pandas numpy
- 下载运行脚本,并在不同的目录中进行数据可视化,命令为:
wget https://raw.githubusercontent.com/osrf/gazebo_tutorials/master/parallel/files/show_parallel_results.py
python3 show_parallel_results.py revolute_joint_test/
python3 show_parallel_results.py pr2/
python3 show_parallel_results.py dual_pr2/
如果看一下pr2仿真场景获得的结果,就会看到孤岛线程对单个PR2场景毫无助益,因为复杂的PR2模型无法被分解到多个线程上同时进行解算。
启动其他实验并尝试了解正在发生的事情。然后对照Gazebo并行物理仿真报告以检查您的想法是否正确。
参考:
获取最新文章: 扫一扫右上角的二维码加入“创客智造”公众号