ROS中阶笔记(四):机器人仿真—Gazebo物理仿真环境搭建(重点)

本文涉及的产品
资源编排,不限时长
简介: ROS中阶笔记(四):机器人仿真—Gazebo物理仿真环境搭建(重点)

1 ros_control


  • ROS为开发者提供的机器人控制中间件
  • 包含一系列控制器接口、传动装置接口、硬件接口、控制器工具箱等等
  • 可以帮助机器人应用功能包快速落地,提高开发效率


aHR0cHM6Ly9naXRlZS5jb20vSVQtY3V0ZS9QaWNiZWQvcmF3L21hc3Rlci9pbWcvaW1hZ2UtMjAyMDA1MTExNzMzMTMxMjIucG5n.png


Controller_manager 与很多controller都已经很完善了,需要写的就是robothw部分


ros_control的功能主要通过controller来实现的


aHR0cHM6Ly9naXRlZS5jb20vSVQtY3V0ZS9QaWNiZWQvcmF3L21hc3Rlci9pbWcvaW1hZ2UtMjAyMDA1MTExNzUwMDIzMDEucG5n.png


1.1 ros_control安装


ros_control需要apt-get命令安装一下,否则这里的launch文件运行不起来,可以通过下列命令安装:


$ sudo apt-get install ros-kinetic-gazebo-ros-control


2 Gazebo仿真步骤(重点)


配置机器人模型

创建仿真环境

开始仿真


2.1 配置物理仿真模型


在~/catkin_ws/src/mbot_description/urdf/xacro/gazebo下,找到mbot_base_gazebo.xacro文件


2.1.1 第一步:为link添加惯性参数和碰撞属性


之前我们创建xacro文件的时候,每个物体只有一个简单的可视化属性,如果要在Gazebo中实现的话,需要对这些可视化模型的每个link添加碰撞属性以及惯性参数。


以base_link为例:

    <link name="base_link">
        <visual>
            <origin xyz=" 0 0 0" rpy="0 0 0" />
            <geometry>
                <cylinder length="${base_length}" radius="${base_radius}"/>
            </geometry>
            <material name="yellow" />
        </visual>
        <collision>
            <origin xyz=" 0 0 0" rpy="0 0 0" />
            <geometry>
                <cylinder length="${base_length}" radius="${base_radius}"/>
            </geometry>
        </collision>   
        <cylinder_inertial_matrix  m="${base_mass}" r="${base_radius}" h="${base_length}" />
    </link>

对比一下前面的base_link,会发现其下面多了一个collision以及cylinder_inertial_matrix,这里需要对每一个link都添加这些属性。关于惯性矩阵的运算,可以自行百度。这里也通过宏定义的形式给出了一个惯性矩阵的计算方式:

<xacro:macro name="sphere_inertial_matrix" params="m r">
    <inertial>
        <mass value="${m}" />
        <inertia ixx="${2*m*r*r/5}" ixy="0" ixz="0"
            iyy="${2*m*r*r/5}" iyz="0" 
            izz="${2*m*r*r/5}" />
    </inertial>
</xacro:macro>
<xacro:macro name="cylinder_inertial_matrix" params="m r h">
    <inertial>
        <mass value="${m}" />
        <inertia ixx="${m*(3*r*r+h*h)/12}" ixy = "0" ixz = "0"
            iyy="${m*(3*r*r+h*h)/12}" iyz = "0"
            izz="${m*r*r/2}" /> 
    </inertial>
</xacro:macro>

上面一个为球体的惯性矩阵计算公式,下面为柱体的计算公式。然后在后面通过调用这些宏来实现惯性矩阵的计算。

同样的,需要给所有的link添加惯性参数和碰撞属性。


2.1.2 第二步:为link添加gazebo标签


标签的主要内容是为了配置每个link在gazebo中的颜色(gazebo与rivz颜色设置不兼容)例如:


给base_link设置了蓝色:

        <gazebo reference="base_link">
            <material>Gazebo/Blue</material>
        </gazebo>

2.1.3 第三步:为joint添加传动装置


由于gazebo的控制是针对于joint做控制的;


例如:我有一个真实的机器人,如果我想让它的轮子动起来,那么我需要一个电机驱动这个轮子做运动。这一步的内容就相当于给我们的机器人模型添加一个电机,也就是一个传动装置:

    <!-- Transmission is important to link the joints and the controller -->
    <transmission name="${prefix}_wheel_joint_trans">
        <type>transmission_interface/SimpleTransmission</type>
        <joint name="${prefix}_wheel_joint" >
            <hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface>
        </joint>
        <actuator name="${prefix}_wheel_joint_motor">
            <hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface>
            <mechanicalReduction>1</mechanicalReduction>
        </actuator>
    </transmission>
</xacro:macro>


2.1.4 第四步:添加gazebo控制器插件(相当于驱动板)


aHR0cHM6Ly9naXRlZS5jb20vSVQtY3V0ZS9QaWNiZWQvcmF3L21hc3Rlci9pbWcvaW1hZ2UtMjAyMDA1MTIwMDMwNTc5MzcucG5n.png


我们现在相当于有了一个模型,通过第三步我们模型有了电机,那我们要让这个电机转起来我们还需要一个控制器,我们给控制器发送一个目标速度这个控制器会发送具体转速给电机,所以在我们的模型文件我们添加一个控制器:


    <gazebo>
        <plugin name="differential_drive_controller" 
                filename="libgazebo_ros_diff_drive.so"> <!-- gazebo提供得差速控制器插件 -->
                <!-- 控制器所需参数 -->
            <rosDebugLevel>Debug</rosDebugLevel>
            <publishWheelTF>true</publishWheelTF>
            <robotNamespace>/</robotNamespace><!-- 机器人命名空间 订阅和发布得话题 前面 会加上命名空间 /说明没有添加-->
            <publishTf>1</publishTf>
            <publishWheelJointState>true</publishWheelJointState>
            <alwaysOn>true</alwaysOn>
            <updateRate>100.0</updateRate>
            <legacyMode>true</legacyMode>
            <leftJoint>left_wheel_joint</leftJoint> <!-- 控制得joint在哪里,必须和上面得joint名称一致 -->
            <rightJoint>right_wheel_joint</rightJoint><!-- 控制得joint在哪里,必须和上面得joint名称一致 -->
            <wheelSeparation>${wheel_joint_y*2}</wheelSeparation><!-- 两个轮子得间距 -->
            <wheelDiameter>${2*wheel_radius}</wheelDiameter>
            <broadcastTF>1</broadcastTF>
            <wheelTorque>30</wheelTorque>
            <wheelAcceleration>1.8</wheelAcceleration>
            <commandTopic>cmd_vel</commandTopic> <!-- 订阅得话题:速度控制指令 -->
            <odometryFrame>odom</odometryFrame> 
            <odometryTopic>odom</odometryTopic> <!-- 发布里程计信息 -->
            <robotBaseFrame>base_footprint</robotBaseFrame><!-- 设置controler所控制的机器人的坐标系是哪个坐标系 -->
        </plugin>
    </gazebo> 


注意:我加入注释是为了更好的理解;xacro中最好不要出现中文,否则可能会报参数问题导致无法正常启动。


2.在gazebo中加载机器人模型


在~/catkin_ws/src/mbot_gazebo/launch/下创建view_mbot_gazebo_empty_world.launch文

<launch>
    <!-- 设置launch文件的参数 -->
    <arg name="paused" default="false"/>
    <arg name="use_sim_time" default="true"/>
    <arg name="gui" default="true"/>
    <arg name="headless" default="false"/>
    <arg name="debug" default="false"/>
    <!-- 运行gazebo仿真环境 -->
    <include file="$(find gazebo_ros)/launch/empty_world.launch">
        <arg name="debug" value="$(arg debug)" />
        <arg name="gui" value="$(arg gui)" />
        <arg name="paused" value="$(arg paused)"/>
        <arg name="use_sim_time" value="$(arg use_sim_time)"/>
        <arg name="headless" value="$(arg headless)"/>
    </include>
    <!-- 加载机器人模型描述参数 -->
    <param name="robot_description" command="$(find xacro)/xacro --inorder '$(find mbot_description)/urdf/xacro/gazebo/mbot_gazebo.xacro'" /> 
    <!-- 运行joint_state_publisher节点,发布机器人的关节状态  -->
    <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" ></node> 
    <!-- 运行robot_state_publisher节点,发布tf  -->
    <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher"  output="screen" >
        <param name="publish_frequency" type="double" value="50.0" />
    </node>
    <!-- 在gazebo中加载机器人模型-->
    <node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn="false" output="screen"
          args="-urdf -model mrobot -param robot_description"/> 
</launch>
$ roslaunch mbot_gazebo view_mbot_gazebo_empty_world.launch 
# 在空环境中可看到机器人模型
建议:为保证模型顺利加载,请提前将模型文件库下载并放置到  ~/.gazebo/models  下
在home文件夹下,ctrl + h 可以查找到所有的隐藏文件  
下载地址:
https://bitbucket.org/osrf/gazebo_models/downloads/


2.2 创建仿真环境


当机器人出现在gazebo的时候,可以看到我们加载的文件里面只有一个机器人,那我们希望能给它添加一些障碍物,这时应该怎么做呢?


2.2.1 方法一:直接添加环境模型


①插入模型


模型放置到~/.gazebo/models 文件夹下——在gazebo的左侧列表点击“insert”(可以看到里面有很多的模型,我们只需要从列表中拖出我们需要的模型放置到仿真环境中就可以)


②保存仿真环境


File——Save World As——放置在功能包~/catkin_ws/src/mbot_gazebo/worlds下面(路径自己选择,主要是在 ~/catkin_ws/src/)


③关闭gazebo界面


如果这些模型不能满足建模需求也可以通过三维设计软件搭建模型放到文件夹中使用。例如solidworks建模


2.2.2 方法二:使用Building Editor


①创建模型


Editor——Building Editor,上面界面用于图形编辑,下面是仿真环境;比如说绘制三维场景中的一堵墙或者一个门。


File——Save保存我们的模型文件(自己设置模型文件名字)——Exit Building Editor(退出编辑界面),可以看到我们的仿真环境已经在gazebo中显示;


②保存仿真环境


File——Save World As——放置在功能包~/catkin_ws/src/mbot_gazebo/worlds下面(路径自己选择,主要是在 ~/catkin_ws/src/)


③关闭gazebo界面


2.2.3 方法二与方法一相结合


2.3 开始仿真


在~/catkin_ws/src/mbot_gazebo/launch下 view_mbot_gazebo_room.launch


如果启动gazebo时希望加载这个模型,可以在launch文件最前面添加:


<!-- 设置launch文件的参数 -->
    <arg name="world_name" value="$(find mbot_gazebo)/worlds/room.world"/>
<!-- 运行gazebo仿真环境 -->
<include file="$(find gazebo_ros)/launch/empty_world.launch">
    <arg name="world_name" value="$(arg world_name)" />
$ roslaunch mbot_gazebo view_mbot_gazebo_room.launch   # 启动仿真环境

下面大家可以进行一些仿真功能的实现


我们希望它能动起来,那么打开一个键盘控制节点:


$ roslaunch mbot_teleop mbot_teleop.launch


同时也可以通过监听odom数据观察机器人的位置。


$ rostopic echo /odom
orientation: # 四元数描述机器人的姿态
x:-2.51798726555e-05
y:-7.59817327643e-06
Z:-0.954841297132
w:0.297116301471


3 传感器仿真


只有机器人的话,并不能做具体的实验,我们希望它能与环境交互,那么我们需要给机器人添加传感器。

类似于之前的控制器插件,gazebo同样拥有很多的传感器插件。


在~/catkin_ws/src/mbot_description/urdf/xacro/sensors/下


3.1 摄像头仿真


在~/catkin_ws/src/mbot_description/urdf/xacro/sensors/下camera_gazebo.xacro文件


aHR0cHM6Ly9naXRlZS5jb20vSVQtY3V0ZS9QaWNiZWQvcmF3L21hc3Rlci9pbWcvaW1hZ2UtMjAyMDA1MTIxODQyNTQzMDAucG5n.png


需要一个摄像头的xacro文件,它需要添加碰撞属性以及惯性属性外,还需要添加摄像头传感器插件,具体代码如下:

<?xml version="1.0"?>
<robot xmlns:xacro="http://www.ros.org/wiki/xacro" name="camera">
    <xacro:macro name="usb_camera" params="prefix:=camera">
        <!-- Create laser reference frame -->
        <link name="${prefix}_link">
            <inertial>
                <mass value="0.1" />
                <origin xyz="0 0 0" />
                <inertia ixx="0.01" ixy="0.0" ixz="0.0"
                         iyy="0.01" iyz="0.0"
                         izz="0.01" />
            </inertial>
            <visual>
                <origin xyz=" 0 0 0 " rpy="0 0 0" />
                <geometry>
                    <box size="0.01 0.04 0.04" />
                </geometry>
                <material name="black"/>
            </visual>
            <collision>
                <origin xyz="0.0 0.0 0.0" rpy="0 0 0" />
                <geometry>
                    <box size="0.01 0.04 0.04" />
                </geometry>
            </collision>
        </link>
        <gazebo reference="${prefix}_link">
            <material>Gazebo/Black</material>
        </gazebo>
        <gazebo reference="${prefix}_link">
            <sensor type="camera" name="camera_node">
                <update_rate>30.0</update_rate>
                <camera name="head">
                    <horizontal_fov>1.3962634</horizontal_fov>
                    <image>
                        <width>1280</width>
                        <height>720</height>
                        <format>R8G8B8</format>
                    </image>
                    <clip>
                        <near>0.02</near>
                        <far>300</far>
                    </clip>
                    <noise>
                        <type>gaussian</type>
                        <mean>0.0</mean>
                        <stddev>0.007</stddev>
                    </noise>
                </camera>
                <plugin name="gazebo_camera" filename="libgazebo_ros_camera.so">
                    <alwaysOn>true</alwaysOn>
                    <updateRate>0.0</updateRate>
                    <cameraName>/camera</cameraName>
                    <imageTopicName>image_raw</imageTopicName>
                    <cameraInfoTopicName>camera_info</cameraInfoTopicName>
                    <frameName>camera_link</frameName>
                    <hackBaseline>0.07</hackBaseline>
                    <distortionK1>0.0</distortionK1>
                    <distortionK2>0.0</distortionK2>
                    <distortionK3>0.0</distortionK3>
                    <distortionT1>0.0</distortionT1>
                    <distortionT2>0.0</distortionT2>
                </plugin>
            </sensor>
        </gazebo>
    </xacro:macro>
</robot>


启动这个带摄像头的模型的launch文件(只是改变机器人模型文件和仿真环境文件路径即可):


$ roslaunch mbot_gazebo view_mbot_with_camera_gazebo.launch


<launch>
    <!-- 设置launch文件的参数 -->
    <arg name="world_name" value="$(find mbot_gazebo)/worlds/playground.world"/><!-- 改这个就行 -->
    <arg name="paused" default="false"/>
    <arg name="use_sim_time" default="true"/>
    <arg name="gui" default="true"/>
    <arg name="headless" default="false"/>
    <arg name="debug" default="false"/>
    <!-- 运行gazebo仿真环境 -->
    <include file="$(find gazebo_ros)/launch/empty_world.launch">
        <arg name="world_name" value="$(arg world_name)" />
        <arg name="debug" value="$(arg debug)" />
        <arg name="gui" value="$(arg gui)" />
        <arg name="paused" value="$(arg paused)"/>
        <arg name="use_sim_time" value="$(arg use_sim_time)"/>
        <arg name="headless" value="$(arg headless)"/>
    </include>
    <!-- 加载机器人模型描述参数 -->
    <param name="robot_description" command="$(find xacro)/xacro --inorder '$(find mbot_description)/urdf/xacro/gazebo/mbot_with_camera_gazebo.xacro'" /> <!-- 改这 -->
    <!-- 运行joint_state_publisher节点,发布机器人的关节状态  -->
    <node name="joint_state_publisher" pkg="joint_state_publisher" type="joint_state_publisher" ></node> 
    <!-- 运行robot_state_publisher节点,发布tf  -->
    <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher"  output="screen" >
        <param name="publish_frequency" type="double" value="50.0" />
    </node>
    <!-- 在gazebo中加载机器人模型-->
    <node name="urdf_spawner" pkg="gazebo_ros" type="spawn_model" respawn="false" output="screen"
          args="-urdf -model mrobot -param robot_description"/> 
</launch>
$ rqt_image_view              # 查看摄像头仿真图像

再启动一个键盘控制节点:


$ roslaunch mbot_teleop mbot_teleop.launch


移动机器人的位置我们会发现图像也是会随之改变。


3.2 RGB-D摄像头仿真(kinect)


加载另外一个launch文件:


$ roslaunch mbot_gazebo view_mbot_with_kinect_gazebo.launch


启动rviz界面查看摄像头的效果:


$ rosrun rviz rviz


添加一个pointcloud2,topic选择/kinect/depth/points。fixed frame选择Kinect_link就可以看到相应的点云信息了。


同样也可以选择添加一个image显示图像信息。


3.3 激光雷达仿真


启动激光雷达launch文件:


$ roslaunch mbot_gazebo view_mbot_with_laser_gazebo.launch


同样可以启动rviz可视化界面查看参数:


$ rosrun rviz rviz
#点击Add一个robotmodel,fixed frame选择odom,可以显示一个机器人模型。
#再添加一个laserscan,topic选择scan。就可以在rviz中显示出激光信息了。size设置激光点大小


4 问题解决


4.1 Gazebo闪退及无法运行(虚拟机中)


在官网下载models文件放在./gazebo文件夹下出现错误,Gazebo闪退及无法运行,提示问题

VMware: vmw_ioctl_command error 无效的参数.
Aborted (core dumped)
[gazebo_gui-3] process has died [pid 3469, exit code 134, cmd /opt/ros/kinetic/lib/gazebo_ros/gzclient __name:=gazebo_gui __log:=/home/ggk/.ros/log/29a04806-93bd-11ea-950a-000c298133c0/gazebo_gui-3.log].
log file: /home/ggk/.ros/log/29a04806-93bd-11ea-950a-000c298133c0/gazebo_gui-3*.log

解决方法:


第一步,关闭虚拟机的3D图形加速:


虚拟机设置—显示器—关闭3D图形加速;


原因:因为虚拟机开启3D图形加速,图形内存不够用,加载不出来


第二步,关闭硬件加速:


echo "export SVGA_VGPU10=0" >> ~/.bashrc
source ~/.bashrc


详细解决方法:https://blog.csdn.net/wangguchao/article/details/88777162


5 参考资料


ros_control http://www.guyuehome.com/890


http://wiki.ros.org/ros_control


rviz与Gazebo的区别


https://www.zhihu.com/question/268658280/answer/340190866


Gazebo仿真教程 http://www.gazebosim.org/tutorials


使用gazebo中的插件 http://www.guyuehome.com/388


相关实践学习
使用ROS创建VPC和VSwitch
本场景主要介绍如何利用阿里云资源编排服务,定义资源编排模板,实现自动化创建阿里云专有网络和交换机。
阿里云资源编排ROS使用教程
资源编排(Resource Orchestration)是一种简单易用的云计算资源管理和自动化运维服务。用户通过模板描述多个云计算资源的依赖关系、配置等,并自动完成所有资源的创建和配置,以达到自动化部署、运维等目的。编排模板同时也是一种标准化的资源和应用交付方式,并且可以随时编辑修改,使基础设施即代码(Infrastructure as Code)成为可能。 产品详情:https://www.aliyun.com/product/ros/
目录
相关文章
|
1月前
|
Ubuntu 机器人 Linux
|
5天前
|
XML 算法 自动驾驶
ROS进阶:使用URDF和Xacro构建差速轮式机器人模型
【11月更文挑战第7天】本篇文章介绍的是ROS高效进阶内容,使用URDF 语言(xml格式)做一个差速轮式机器人模型,并使用URDF的增强版xacro,对机器人模型文件进行二次优化。
|
10天前
|
自动驾驶 安全 机器人
ROS2:从初识到深入,探索机器人操作系统的进化之路
【11月更文挑战第4天】ROS2的学习过程和应用,介绍DDS系统的框架和知识。
|
1月前
|
传感器 数据可视化 机器人
【ROS速成】半小时入门机器人ROS系统简明教程之可视化系统(三)
半小时入门机器人ROS系统简明教程之可视化系统
|
1月前
|
机器人
【ROS速成】半小时入门机器人ROS系统简明教程之安装测速(二)
半小时入门机器人ROS系统简明教程之安装测速
|
3月前
|
XML 传感器 数据可视化
09 机器人仿真Gazebo实例
本文详细介绍了在ROS(机器人操作系统)中使用Gazebo进行机器人仿真的流程,包括安装Gazebo、创建URDF模型、使用xacro优化URDF、配置ROS_control以及为模型添加Gazebo属性和控制器插件,并提供了相应的示例代码。
142 0
|
5月前
|
机器人 定位技术 C++
技术笔记:ROS中测试机器人里程计信息
技术笔记:ROS中测试机器人里程计信息
|
6月前
|
传感器 人工智能 算法
ROS机器人操作系统
ROS机器人操作系统
174 1
|
5月前
|
机器学习/深度学习 传感器 算法
强化学习(RL)在机器人领域的应用,尤其是结合ROS(Robot Operating System)和Gazebo(机器人仿真环境)
强化学习(RL)在机器人领域的应用,尤其是结合ROS(Robot Operating System)和Gazebo(机器人仿真环境)
230 2
|
6月前
|
NoSQL 机器人 Windows
ROS机器人编程技术控制两只小海龟的编队运动
ROS机器人编程技术控制两只小海龟的编队运动
227 1

推荐镜像

更多