006 机器人仿真
机器人仿真
常见仿真软件
目前市面上有许多机器人仿真软件,这些仿真软件其实是独立于ROS的,他们是通过一些物理引擎做的。通过一些插件,可以让这些仿真软件和ROS2结合。下面的笔记全是基于Gazebo的
所需参数
仿真时URDF文件必须定义一些子标签:
- 碰撞(collison标签)
- 内参:包括物体质量(mass标签)、旋转惯量(inertia标签)、摩擦力(gazebo扩展的一些标签)
Gazebo的使用
Gazebo本身是个与ROS无关的软件,必须通过一些插件,才能让它和ROS2结合
启动
直接启动Gazebo的话,不会启动对应的ROS2 node,这样的话就无法和ROS2联动了。所以启动Gazebo的时候必须指定ROS2插件
1 | gazebo --verbose -s libgazebo_ros_init.so -s libgazebo_ros_factory.so |
此时会创建一个叫/gazebo
的ROS节点,该节点创建了一些service
,让我们可以与其交互(gazeo里面本身也有一些GUI操作工具,但是无法直接加载urdf文件)
1 | ros2 service list |
加载模型
ROS2中的gazebo_ros2
功能包提供了一个节点(spawn_entity.py
),这个节点会调用/spawn_entity
服务,我们只需要在启动节点时设置一些参数,即可加载不同的模型进Gazebo
插件机制
Gazebo本体提供的功能并不多,为了在不修改其源码的情况下,对其工作做一些扩展(新增传感器、集成ROS、直接访问物理引擎…)它提供了一种插件机制。用户可以通过写插件(动态库),来实现对Gazebo进行二次开发,插件按功能可以分为以下几类:
插件类型 | 作用对象 | 典型应用 |
---|---|---|
WorldPlugin | 整个仿真世界 | 全局物理规则、环境动态变化(如天气) |
ModelPlugin | 单个模型 | 机器人运动控制、机械臂逆运动学 |
SensorPlugin | 传感器 | 激光雷达噪声模拟、摄像头图像生成 |
SystemPlugin | Gazebo系统本身 | 自定义命令行参数、日志记录 |
VisualPlugin | 可视化元素 | 渲染特效(如粒子系统) |
GUIPlugin | 用户界面 | 添加自定义按钮或显示面板 |
通过
ls /opt/ros/humble/lib/libgazebo_ros*
可以看当前安装了什么插件
工作原理
插件加载流程
声明插件:在URDF/SDF文件中通过
<plugin>
标签指定插件库路径和参数:1
2
3
4
5<model name="robot">
<plugin name="diff_drive" filename="libgazebo_ros_diff_drive.so">
<wheel_separation>0.5</wheel_separation>
</plugin>
</model>动态加载:Gazebo启动时通过
dlopen()
加载插件库,调用注册函数创建插件实例初始化:插件重写基类的
Load()
方法,获取仿真对象(如模型指针)并绑定事件回调
事件响应机制
插件通过Gazebo的事件系统(如WorldUpdateBegin
)实时响应仿真状态:
1 | void MyPlugin::Load(gazebo::physics::ModelPtr _model, sdf::ElementPtr _sdf) { |
通信方式
- 内部通信:插件直接访问Gazebo的API(如
physics::World
)修改仿真状态 - 外部通信:通过ROS话题/服务(如
libgazebo_ros_imu.so
发布/imu/data
)与外部系统交互
这些插件如果要和ROS交互,一般会作为一个node,与其他节点进行通信。在使用插件时,我们应该重点关注这些插件节点的输入和输出是什么
数据流
在同时使用ROS2、Gazebo、RVIZ的时候,数据流一般是这样的:
1 | ros2->gazebo->rviz |
首先通过ROS2节点往Gazebo的运动控制/传感器插件发数据,这些插件在计算完后,会将结果以topic的形式广播,再用RVIZ订阅这些topic就行了