目录
一、RVIZ中控制机器人的运动
1.1 arbotix简介
1.简介
arbotix是一款控制电机、舵机的控制板,并提供相应的ros包,这个功能包的功能不仅可以驱动真实的arbotix控制板,它还提供一个差速控制器,通过接收速度控制指令更新机器人的joint状态,从而帮助我们实现机器人在rviz中的运动
1.2 控制机器人模型在 rviz 中做圆周运动
1.2.1 实现流程
安装 Arbotix
创建新功能包,准备机器人 urdf、xacro 文件
添加 Arbotix 配置文件
编写 launch 文件配置 Arbotix
启动 launch 文件并控制机器人模型运动
1.2.2 具体实现
Ⅰ.安装Arbotix
在当前工作空间下下载相应控件
git clone -b indigo-devel https://github.com/vanadiumlabs/arbotix_ros.git
cd ..
catkin_make
这样就是安装好啦!
Ⅱ.创建新功能包,准备机器人 urdf、xacro 文件
Ⅲ.添加arbotix所需的配置文件 control.yaml
# 该文件是控制器配置,一个机器人模型可能有多个控制器,比如: 底盘、机械臂、夹持器(机械手).... # 因此,根 name 是 controller controllers: { # 单控制器设置 base_controller: { #类型: 差速控制器 type: diff_controller, #参考坐标 base_frame_id: base_footprint, #两个轮子之间的间距 base_width: 0.2, #控制频率 ticks_meter: 2000, #PID控制参数,使机器人车轮快速达到预期速度 Kp: 12, Kd: 12, Ki: 0, Ko: 50, #加速限制 accel_limit: 1.0 } }
Ⅳ.编写 launch 文件配置 Arbotix
<launch> <param name="robot_description" command="$(find xacro)/xacro $(find urdf_rviz)/urdf/xacro/car.urdf.xacro" /> <node pkg="rviz" type="rviz" name="rviz" args="-d $(find urdf_rviz)/config/show_mycar.rviz" /> <!-- 添加关节状态发布节点 --> <node pkg="joint_state_publisher" type="joint_state_publisher" name="joint_state_publisher" /> <!-- 添加机器人状态发布节点 --> <node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher" /> <!--集成arbotix 控制结点,并且加载参数--> <node pkg = "arbotix_python" type = "arbotix_driver" name = "driver" output = "screen" > <rosparam command = "load" file = "$(find urdf_rviz)/config/control.yaml" /> <param name = "sim" value = "true"/> </launch>
Ⅴ.启动 launch 文件并控制机器人模型运动
liuhongwei@liuhongwei-virtual-machine:~/demo05_ws$ rostopic pub -r 10 /cmd_vel geometry_msgs/Twist "linear: x: 1.0 y: 0.0 z: 0.0 angular: x: 0.0 y: 0.0 z: 1.0"
二、URDF集成Gazebo
2.1 本章主要内容
URDF 需要集成进 Rviz 或 Gazebo 才能显示可视化的机器人模型,前面已经介绍了URDF 与 Rviz 的集成,本节主要介绍:
- URDF 与 Gazebo 的基本集成流程;
- 如果要在 Gazebo 中显示机器人模型,URDF 需要做的一些额外配置;
- 关于Gazebo仿真环境的搭建。
2.2 URDF与Gazebo基本集成流程
2.2.1 URDF与Gazebo基本集成流程
1.主要步骤
创建功能包,导入依赖项
编写 URDF 或 Xacro 文件
启动 Gazebo 并显示机器人模型
2.具体实现流程
Ⅰ.创建功能包 urdf02_gazebo ,导入依赖 urdf xacro gazebo_ros gazebo_ros_control gazebo_plugins。
Ⅱ.gazebo集成需要urdf设置碰撞参数与惯性矩阵参数
①碰撞参数的设置:如果是标准几何体,直接复制visual的geometry和origin即可
②惯性矩阵
③gazebo有自己的颜色设置
<robot name="mycar"> <link name="base_link"> <visual> <geometry> <box size="0.5 0.2 0.1" /> </geometry> <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" /> <material name="yellow"> <color rgba="0.5 0.3 0.0 1" /> </material> </visual> <collision> <geometry> <box size="0.5 0.2 0.1" /> </geometry> <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0" /> </collision> <inertial> <origin xyz="0 0 0" /> <mass value="6" /> <inertia ixx="1" ixy="0" ixz="0" iyy="1" iyz="0" izz="1" /> </inertial> </link> <gazebo reference="base_link"> <material>Gazebo/Black</material> </gazebo> </robot>
Ⅲ.将urdf集成到launch文件中,并启动gazebo
<launch> <!-- 将 Urdf 文件的内容加载到参数服务器 --> <param name="robot_description" textfile="$(find urdf02_gazebo)/urdf/demo01_helloworld.urdf" /> <!-- 启动 gazebo --> <include file="$(find gazebo_ros)/launch/empty_world.launch" /> <!-- 在 gazebo 中显示机器人模型 --> <node pkg="gazebo_ros" type="spawn_model" name="model" args="-urdf -model mycar -param robot_description" /> </launch>
2.2.2 URDF集成Gazebo相关设置
1.collision
如果机器人link是标准的几何体形状,和link的 visual 属性设置一致即可。
2.inertial
惯性矩阵的设置需要结合link的质量与外形参数动态生成,标准的球体、圆柱与立方体的惯性矩阵公式如下(已经封装为 xacro 实现):
Ⅰ.球体惯性矩阵
<!-- Macro for inertia matrix --> <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>
Ⅲ.立方体惯性矩阵
<xacro:macro name="Box_inertial_matrix" params="m l w h"> <inertial> <mass value="${m}" /> <inertia ixx="${m*(h*h + l*l)/12}" ixy = "0" ixz = "0" iyy="${m*(w*w + l*l)/12}" iyz= "0" izz="${m*(w*w + h*h)/12}" /> </inertial> </xacro:macro>
2.2.3 案例:URDF集成Gazebo实操
1.需求
将之前的机器人模型(xacro版)显示在 gazebo 中
2.实现流程
需要编写封装惯性矩阵算法的 xacro 文件
为机器人模型中的每一个 link 添加 collision 和 inertial 标签,并且重置颜色属性
在 launch 文件中启动 gazebo 并添加机器人模型
3.具体实现
Ⅰ.封装惯性矩阵算法的 xacro 文件:head.xacro
<robot name="base" xmlns:xacro="http://wiki.ros.org/xacro"> <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> <xacro:macro name="Box_inertial_matrix" params="m l w h"> <inertial> <mass value="${m}" /> <inertia ixx="${m*(h*h + l*l)/12}" ixy = "0" ixz = "0" iyy="${m*(w*w + l*l)/12}" iyz= "0" izz="${m*(w*w + h*h)/12}" /> </inertial> </xacro:macro> </robot>
Ⅱ.框架搭建
①car.urdf 修改要包含惯性矩阵文件
<robot name = "mycar" xmlns:xacro="http://www.ros.org/wiki/xacro"> <xacro:include filename = "head.xacro"/> <xacro:include filename = "demo05_carbase.urdf.xacro"/> <xacro:include filename = "demo06_carcamera.urdf.xacro"/> <xacro:include filename = "demo07_carlaser.urdf.xacro"/> </robot>
②搭建launch文件
<launch> <!-- 将 Urdf 文件的内容加载到参数服务器 --> <param name="robot_description" command="$(find xacro)/xacro $(find urdf02_gazebo)/urdf/car.urdf.xacro" /> <!-- 启动 gazebo --> <include file="$(find gazebo_ros)/launch/empty_world.launch" /> <!-- 在 gazebo 中显示机器人模型 --> <node pkg="gazebo_ros" type="spawn_model" name="model" args="-urdf -model mycar -param robot_description" /> </launch>
Ⅲ.为机器人模型中的每一个 link 添加 collision 和 inertial 标签,并且重置颜色属性
① 修改 demo05_carbase.urdf.xacro
<robot name = "mycar" xmlns:xacro="http://www.ros.org/wiki/xacro"> <xacro:property name = "footfrintradius" value = "0.001"/> <xacro:property name = "base_radius" value = "0.1" /> <xacro:property name = "base_length" value = "0.08" /> <xacro:property name = "lidi" value = "0.015" /> <xacro:property name = "base_joint_z" value = "${base_length/2+ lidi }" /> <xacro:property name = "wheel_radius" value = "0.0325" /> <xacro:property name = "wheel_length" value = "0.015" /> <xacro:property name = "PI" value = "3.1415927" /> <xacro:property name = "wheel_joint_z" value = "${wheel_radius - (base_length/2 +lidi)}" /> <xacro:property name = "small_wheel_radius" value = "0.0075" /> <xacro:property name = "small_joint_z" value = "${-(base_length/2+lidi-small_wheel_radius)}" /> <link name="base_footprint"> <visual> <geometry> <sphere radius="${footfrintradius}" /> </geometry> </visual> </link> <link name="base_link"> <visual> <geometry> <cylinder radius="${base_radius}" length="${base_length}" /> </geometry> <origin xyz="0 0 0" rpy="0 0 0" /> <material name="yellow"> <color rgba="0.8 0.3 0.1 0.5" /> </material> </visual> <collision> <geometry> <cylinder radius="${base_radius}" length="${base_length}" /> </geometry> <origin xyz="0 0 0" rpy="0 0 0" /> </collision> <xacro:cylinder_inertial_matrix m = "2" r = "${base_radius}" h ="${base_length}"/> </link> <gazebo reference = "base_link"> <material>Gazebo/Yellow</material> </gazebo> <joint name="base_link2base_footprint" type="fixed"> <parent link="base_footprint" /> <child link="base_link"/> <origin xyz="0 0 ${base_joint_z}" /> </joint> <xacro:macro name = "wheel_func" params = "wheel_name flag"> <link name="${wheel_name}_wheel"> <visual> <geometry> <cylinder radius="${wheel_radius}" length="${wheel_length}" /> </geometry> <origin xyz="0 0 0" rpy="${PI / 2} 0 0" /> <material name="black"> <color rgba="0.0 0.0 0.0 1.0" /> </material> </visual> <collision> <geometry> <cylinder radius="${wheel_radius}" length="${wheel_length}" /> </geometry> <origin xyz="0 0 0" rpy="${PI / 2} 0 0" /> </collision> <xacro:cylinder_inertial_matrix m = "0.05" r = "${wheel_radius}" h = "${wheel_length}" /> </link> <gazebo reference = "${wheel_name}_wheel"> <material>Gazebo/Red</material> </gazebo> <joint name="${wheel_name}2link" type="continuous"> <parent link="base_link" /> <child link="${wheel_name}_wheel" /> <origin xyz="0 ${0.1 * flag} ${wheel_joint_z}" /> <axis xyz="0 1 0" /> </joint> </xacro:macro> <xacro:wheel_func wheel_name = "left" flag = "1"/> <xacro:wheel_func wheel_name = "right" flag = "-1"/> <xacro:macro name = "small_wheel_func" params = "small_wheel_name flag"> <link name="${small_wheel_name}_wheel"> <visual> <geometry> <sphere radius="${small_wheel_radius}" /> </geometry> <origin xyz="0 0 0" rpy="0 0 0" /> <material name="black"> <color rgba="0.0 0.0 0.0 1.0" /> </material> </visual> <collision> <geometry> <sphere radius="${small_wheel_radius}" /> </geometry> <origin xyz="0 0 0" rpy="0 0 0" /> </collision> <xacro:sphere_inertial_matrix m = "0.01" r = "${small_wheel_radius}"/> </link> <gazebo reference = "${small_wheel_name}_wheel"> <material>Gazebo/Red</material> </gazebo> <joint name="${small_wheel_name}2link" type="continuous"> <parent link="base_link" /> <child link="${small_wheel_name}_wheel" /> <origin xyz="${0.08*flag} 0 ${small_joint_z}" /> <axis xyz="1 1 1" /> </joint> </xacro:macro> <xacro:small_wheel_func small_wheel_name = "front" flag = "1"/> <xacro:small_wheel_func small_wheel_name = "back" flag = "-1"/> </robot>
② 修改 demo06_carcamera.urdf.xacro
<robot name = "my_camera" xmlns:xacro="http://www.ros.org/wiki/xacro"> <xacro:property name = "camera_x" value = "0.02" /> <xacro:property name = "camera_y" value = "0.05" /> <xacro:property name = "camera_z" value = "0.05" /> <xacro:property name = "joint_camera_x" value = "0.08" /> <xacro:property name = "joint_camera_y" value = "0" /> <xacro:property name = "base_length" value = "0.08" /> <xacro:property name = "joint_camera_z" value = "${camera_z /2 +base_length/2 }" /> <link name="camera"> <visual> <geometry> <box size="${camera_x} ${camera_y} ${camera_z}"/> </geometry> <material name = "no" > <color rgba = "3 3 3 0.3"/> </material> </visual> <collision> <geometry> <box size="${camera_x} ${camera_y} ${camera_z}"/> </geometry> </collision> <xacro:Box_inertial_matrix m = "0.01" l= "${camera_x}" w="${camera_y}" h="${camera_z}" /> </link> <gazebo reference = "camera"> <material>Gazebo/Blue</material> </gazebo> <joint name="camera2baselink" type="fixed"> <origin xyz="${joint_camera_x} ${joint_camera_y} ${joint_camera_z}" rpy="0.0 0.0 0.0"/> <parent link="base_link"/> <child link="camera"/> <axis xyz="0.0 0.0 0.0"/> </joint> </robot>
③ 修改 demo07_carlaser.urdf.xacro
<robot name = "mylaser" xmlns:xacro="http://www.ros.org/wiki/xacro"> <xacro:property name = "support_radius" value = "0.01" /> <xacro:property name = "support_length" value = "0.15" /> <xacro:property name = "laser_radius" value = "0.03" /> <xacro:property name = "laser_length" value = "0.05" /> <xacro:property name = "joint_support_x" value = "0.00" /> <xacro:property name = "joint_support_y" value = "0.00" /> <xacro:property name = "joint_support_z" value = "${base_length / 2 +support_length / 2}" /> <xacro:property name = "joint_laser_x" value = "0.00" /> <xacro:property name = "joint_laser_y" value = "0.00" /> <xacro:property name = "joint_laser_z" value = "${support_length/2 + laser_length/2}" /> <link name="support"> <visual> <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0"/> <geometry> <cylinder radius = "${support_radius}" length = "${support_length}"/> </geometry> <material name="sha"> <color rgba="0.8 0.5 0.0 0.5"/> </material> </visual> <collision> <geometry> <cylinder radius = "${support_radius}" length = "${support_length}"/> </geometry> </collision> <xacro:cylinder_inertial_matrix m = "0.1" r = "${support_radius}" h="${support_length}" /> </link> <gazebo reference = "support"> <material>Gazebo/Grey</material> </gazebo> <joint name="support2base" type="fixed"> <parent link = "base_link"/> <child link = "support" /> <origin xyz = "${joint_support_x} ${joint_support_y} ${joint_support_z}" rpy = "0 0 0" /> </joint> <link name="laser"> <visual> <origin xyz="0.0 0.0 0.0" rpy="0.0 0.0 0.0"/> <geometry> <cylinder radius = "${laser_radius}" length = "${laser_length}"/> </geometry> <material name="shav"> <color rgba="0.0 0.0 0.0 0.5"/> </material> </visual> <collision> <geometry> <cylinder radius = "${laser_radius}" length = "${laser_length}"/> </geometry> </collision> <xacro:cylinder_inertial_matrix m = "0.15" r = "${laser_radius}" h = "${laser_length}"/> </link> <gazebo reference = "laser"> <material>Gazebo/Black</material> </gazebo> <joint name="laser2support" type="fixed"> <parent link = "support"/> <child link = "laser" /> <origin xyz = "${joint_laser_x} ${joint_laser_y} ${joint_laser_z}" rpy = "0 0 0" /> </joint> </robot>
2.2.4 Gazebo仿真环境搭建
1.如何导入外置world文件
新建立文件夹,导入world文件,修改launch文件
<launch> <!-- 将 Urdf 文件的内容加载到参数服务器 --> <param name="robot_description" command="$(find xacro)/xacro $(find urdf02_gazebo)/urdf/car.urdf.xacro" /> <!-- 启动 gazebo name名称固定 value定位--> <include file="$(find gazebo_ros)/launch/empty_world.launch" > <arg name = "world_name" value = "$(find urdf02_gazebo)/worlds/box_house.world" /> </include> <!-- 在 gazebo 中显示机器人模型 --> <node pkg="gazebo_ros" type="spawn_model" name="model" args="-urdf -model mycar -param robot_description" /> </launch>
执行
2.如何搭建仿真环境
到目前为止,我们已经可以将机器人模型显示在 Gazebo 之中了,但是当前默认情况下,在 Gazebo 中机器人模型是在 empty world 中,并没有类似于房间、家具、道路、树木... 之类的仿真物,如何在 Gazebo 中创建仿真环境呢?
Gazebo 中创建仿真实现方式有两种:
方式1: 直接添加内置组件创建仿真环境
方式2: 手动绘制仿真环境(更为灵活)
具体步骤实现:添加内置组件创建仿真环境:开启gazebo
rosrun gazebo_ros gazebo
Ⅰ.画图
Ⅱ.保存
具体步骤实现:手动绘制仿真环境(更为灵活)
Ⅰ.
Ⅱ.开始绘画!! 电脑比较卡!!!
2.3 URDF、Gazebo与Rviz的综合应用
2.3.1 本节概述
关于URDF(Xacro)、Rviz 和 Gazebo 三者的关系,前面已有阐述: URDF 用于创建机器人模型、Rviz 可以显示机器人感知到的环境信息,Gazebo 用于仿真,可以模拟外界环境,以及机器人的一些传感器,如何在 Gazebo 中运行这些传感器,并显示这些传感器的数据(机器人的视角)呢?本节主要介绍的重点就是将三者结合:通过 Gazebo 模拟机器人的传感器,然后在 Rviz 中显示这些传感器感知到的数据。主要内容包括:
运动控制以及里程计信息显示
雷达信息仿真以及显示
摄像头信息仿真以及显示
kinect 信息仿真以及显示
2.3.2 机器人运动控制以及里程计信息显示
1.需求
gazebo 中已经可以正常显示机器人模型了,那么如何像在 rviz 中一样控制机器人运动呢?在此,需要涉及到ros中的组件: ros_control。
2.ros_control简介
Ⅰ.场景:同一套 ROS 程序,如何部署在不同的机器人系统上,比如:开发阶段为了提高效率是在仿真平台上测试的,部署时又有不同的实体机器人平台,不同平台的实现是有差异的,如何保证 ROS 程序的可移植性?ROS 内置的解决方式是 ros_control。
Ⅱ.ros_control:
是一组软件包,它包含了控制器接口,控制器管理器,传输和硬件接口。ros_control 是一套机器人控制的中间件,是一套规范,不同的机器人平台只要按照这套规范实现,那么就可以保证 与ROS 程序兼容,通过这套规范,实现了一种可插拔的架构设计,大大提高了程序设计的效率与灵活性。
gazebo 已经实现了 ros_control 的相关接口,如果需要在 gazebo 中控制机器人运动,直接调用相关接口即可
3.运动控制实现流程(Gazebo)
已经创建完毕的机器人模型,编写一个单独的 xacro 文件,为机器人模型添加传动装置以及控制器
将此文件集成进xacro文件
启动 Gazebo 并发布 /cmd_vel 消息控制机器人运动
4.实现
Ⅰ.框架搭建
新建 move.xacro 文件,将其集成进 car.urdf.xacro 文件中
<robot name = "mycar" xmlns:xacro="http://www.ros.org/wiki/xacro"> <xacro:include filename = "head.xacro"/> <xacro:include filename = "demo05_carbase.urdf.xacro"/> <xacro:include filename = "demo06_carcamera.urdf.xacro"/> <xacro:include filename = "demo07_carlaser.urdf.xacro"/> <!--集成运动--> <xacro:include filename = "move.xacro"/> </robot>
写launch文件
<launch> <!-- 将 Urdf 文件的内容加载到参数服务器 --> <param name="robot_description" command="$(find xacro)/xacro $(find urdf02_gazebo)/urdf/car.urdf.xacro" /> <!-- 启动 gazebo name名称固定 value定位--> <include file="$(find gazebo_ros)/launch/empty_world.launch" > <arg name = "world_name" value = "$(find urdf02_gazebo)/worlds/box_house.world" /> </include> <!-- 在 gazebo 中显示机器人模型 --> <node pkg="gazebo_ros" type="spawn_model" name="model" args="-urdf -model mycar -param robot_description" /> </launch>
Ⅱ.move.xacro的实现
<robot name="my_car_move" xmlns:xacro="http://wiki.ros.org/xacro"> <!-- 传动实现:用于连接控制器与关节 --> <xacro:macro name="joint_trans" params="joint_name"> <!-- Transmission is important to link the joints and the controller --> <transmission name="${joint_name}_trans"> <type>transmission_interface/SimpleTransmission</type> <joint name="${joint_name}"> <hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface> </joint> <actuator name="${joint_name}_motor"> <hardwareInterface>hardware_interface/VelocityJointInterface</hardwareInterface> <mechanicalReduction>1</mechanicalReduction> </actuator> </transmission> </xacro:macro> <!-- 每一个驱动轮都需要配置传动装置 --> <xacro:joint_trans joint_name="left2link" /> <xacro:joint_trans joint_name="right2link" /> <!-- 控制器 --> <gazebo> <plugin name="differential_drive_controller" filename="libgazebo_ros_diff_drive.so"> <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>left2link</leftJoint> <!-- 左轮 --> <rightJoint>right2link</rightJoint> <!-- 右轮 --> <wheelSeparation>${base_radius* 2}</wheelSeparation> <!-- 车轮间距 --> <wheelDiameter>${wheel_radius* 2}</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> <!-- 根坐标系 --> </plugin> </gazebo> </robot>
Ⅲ.控制小车动起来
解决完毕后:键入命令行
rosrun teleop_twist_keyboard teleop_twist_keyboard.py
这时可以控制小车运动
Ⅳ.Rviz查看里程计消息
①配置launch文件
<launch> <node pkg="rviz" type="rviz" name="rviz" args="-d $(find urdf_rviz)/config/show_mycar.rviz" /> <node pkg="joint_state_publisher" type="joint_state_publisher" name="joint_state_publisher" /> <node pkg="robot_state_publisher" type="robot_state_publisher" name="robot_state_publisher" /> </launch>
②执行它
先执行仿真环境
roslaunch urdf02_gazebo demo03_env.launch
再执行上述launch文件
liuhongwei@liuhongwei-virtual-machine:~$ cd demo05_ws/ liuhongwei@liuhongwei-virtual-machine:~/demo05_ws$ source ./devel/setup.bash liuhongwei@liuhongwei-virtual-machine:~/demo05_ws$ roslaunch urdf02_gazebo demo04_sensor.launch
修改里程计配置
![]()
![]()
2.3.3 雷达信息仿真以及显示
1.实现流程
摄像头仿真基本流程:
已经创建完毕的机器人模型,编写一个单独的 xacro 文件,为机器人模型添加摄像头配置;
将此文件集成进xacro文件;
启动 Gazebo,使用 Rviz 显示摄像头信息。
2.具体实现
Ⅰ. 编写一个单独的 xacro 文件,为雷达模型添加摄像头配置(laser.xacro)
<robot name="my_sensors" xmlns:xacro="http://wiki.ros.org/xacro"> <!-- 雷达 --> <gazebo reference="laser"> <sensor type="ray" name="rplidar"> <pose>0 0 0 0 0 0</pose> <visualize>true</visualize> <update_rate>5.5</update_rate> <ray> <scan> <horizontal> <samples>360</samples> <resolution>1</resolution> <min_angle>-3</min_angle> <max_angle>3</max_angle> </horizontal> </scan> <range> <min>0.10</min> <max>30.0</max> <resolution>0.01</resolution> </range> <noise> <type>gaussian</type> <mean>0.0</mean> <stddev>0.01</stddev> </noise> </ray> <plugin name="gazebo_rplidar" filename="libgazebo_ros_laser.so"> <topicName>/scan</topicName> <frameName>laser</frameName> </plugin> </sensor> </gazebo> </robot>
Ⅱ.将此文件集成进car.urdf.xacro文件
<robot name = "mycar" xmlns:xacro="http://www.ros.org/wiki/xacro"> <xacro:include filename = "head.xacro"/> <xacro:include filename = "demo05_carbase.urdf.xacro"/> <xacro:include filename = "demo06_carcamera.urdf.xacro"/> <xacro:include filename = "demo07_carlaser.urdf.xacro"/> <!--集成运动--> <xacro:include filename = "move.xacro"/> <xacro:include filename = "laser.xacro"/> </robot>
Ⅲ.执行
首先启动gazebo
roslaunch urdf02_gazebo demo03_env.launch
启动rviz
roslaunch urdf02_gazebo demo04_sensor.launch
2.3.4 摄像头仿真以及显示
1.基本流程
已经创建完毕的机器人模型,编写一个单独的 xacro 文件,为机器人模型添加摄像头配置;
将此文件集成进xacro文件;
启动 Gazebo,使用 Rviz 显示摄像头信息。
2.实现步骤
Ⅰ. 编写一个单独的 xacro 文件,为机器人模型添加摄像头配置 camera.xacro
<robot name="my_sensors" xmlns:xacro="http://wiki.ros.org/xacro"> <gazebo reference="support"> <sensor type="depth" name="camera"> <always_on>true</always_on> <update_rate>20.0</update_rate> <camera> <horizontal_fov>${60.0*PI/180.0}</horizontal_fov> <image> <format>R8G8B8</format> <width>640</width> <height>480</height> </image> <clip> <near>0.05</near> <far>8.0</far> </clip> </camera> <plugin name="kinect_camera_controller" filename="libgazebo_ros_openni_kinect.so"> <cameraName>camera</cameraName> <alwaysOn>true</alwaysOn> <updateRate>10</updateRate> <imageTopicName>rgb/image_raw</imageTopicName> <depthImageTopicName>depth/image_raw</depthImageTopicName> <pointCloudTopicName>depth/points</pointCloudTopicName> <cameraInfoTopicName>rgb/camera_info</cameraInfoTopicName> <depthImageCameraInfoTopicName>depth/camera_info</depthImageCameraInfoTopicName> <frameName>support</frameName> <baseline>0.1</baseline> <distortion_k1>0.0</distortion_k1> <distortion_k2>0.0</distortion_k2> <distortion_k3>0.0</distortion_k3> <distortion_t1>0.0</distortion_t1> <distortion_t2>0.0</distortion_t2> <pointCloudCutoff>0.4</pointCloudCutoff> </plugin> </sensor> </gazebo> </robot>
Ⅱ.将此文件集成进xacro文件
<robot name = "mycar" xmlns:xacro="http://www.ros.org/wiki/xacro"> <xacro:include filename = "head.xacro"/> <xacro:include filename = "demo05_carbase.urdf.xacro"/> <xacro:include filename = "demo06_carcamera.urdf.xacro"/> <xacro:include filename = "demo07_carlaser.urdf.xacro"/> <!--集成运动--> <xacro:include filename = "move.xacro"/> <xacro:include filename = "laser.xacro"/> <xacro:include filename = "camera.xacro"/> </robot>
Ⅲ.启动 Gazebo,使用 Rviz 显示摄像头信息。
![]()
2.3.5 kinect深度相机仿真
1.实现流程
已经创建完毕的机器人模型,编写一个单独的 xacro 文件,为机器人模型添加kinect摄像头配置;
将此文件集成进xacro文件;
启动 Gazebo,使用 Rviz 显示kinect摄像头信息。
2.具体步骤
Ⅰ.编写一个单独的 xacro 文件,为机器人模型添加kinect摄像头配置
<robot name="my_sensors" xmlns:xacro="http://wiki.ros.org/xacro"> <gazebo reference="support"> <sensor type="depth" name="camera"> <always_on>true</always_on> <update_rate>20.0</update_rate> <camera> <horizontal_fov>${60.0*PI/180.0}</horizontal_fov> <image> <format>R8G8B8</format> <width>640</width> <height>480</height> </image> <clip> <near>0.05</near> <far>8.0</far> </clip> </camera> <plugin name="kinect_camera_controller" filename="libgazebo_ros_openni_kinect.so"> <cameraName>camera</cameraName> <alwaysOn>true</alwaysOn> <updateRate>10</updateRate> <imageTopicName>rgb/image_raw</imageTopicName> <depthImageTopicName>depth/image_raw</depthImageTopicName> <pointCloudTopicName>depth/points</pointCloudTopicName> <cameraInfoTopicName>rgb/camera_info</cameraInfoTopicName> <depthImageCameraInfoTopicName>depth/camera_info</depthImageCameraInfoTopicName> <frameName>support</frameName> <baseline>0.1</baseline> <distortion_k1>0.0</distortion_k1> <distortion_k2>0.0</distortion_k2> <distortion_k3>0.0</distortion_k3> <distortion_t1>0.0</distortion_t1> <distortion_t2>0.0</distortion_t2> <pointCloudCutoff>0.4</pointCloudCutoff> </plugin> </sensor> </gazebo> </robot>
Ⅱ.将此文件集成进xacro文件
<robot name = "mycar" xmlns:xacro="http://www.ros.org/wiki/xacro"> <xacro:include filename = "head.xacro"/> <xacro:include filename = "demo05_carbase.urdf.xacro"/> <xacro:include filename = "demo06_carcamera.urdf.xacro"/> <xacro:include filename = "demo07_carlaser.urdf.xacro"/> <!--集成运动--> <xacro:include filename = "move.xacro"/> <xacro:include filename = "laser.xacro"/> <xacro:include filename = "camera.xacro"/> <xacro:include filename = "kinect.xacro"/> </robot>
Ⅲ.演示
2.3.6 kinect点云数据显示
1.实现
Ⅰ.在上节的rviz实现中添加组件点云
Ⅱ.设置topic为 /camera/depth/points
Ⅲ.如图所示
问题:在rviz中显示时错位。
原因:在kinect中图像数据与点云数据使用了两套坐标系统,且两套坐标系统位姿并不一致。
解决:
1.在插件中为kinect设置坐标系,修改配置文件的
<frameName>
标签内容:<frameName>support_depth</frameName>
2.发布新设置的坐标系到kinect连杆的坐标变换关系,在启动rviz的launch中,添加:
<node pkg="tf2_ros" type="static_transform_publisher" name="static_transform_publisher" args="0 0 0 -1.57 0 -1.57 /support /support_depth" />
3.重启rviz查看
2.4 本章小结
本章主要介绍了ROS中仿真实现涉及的三大知识点:
- URDF(Xacro)
- Rviz
- Gazebo
URDF 是用于描述机器人模型的 xml 文件,可以使用不同的标签具代表不同含义,URDF 编写机器人模型代码冗余,xacro 可以优化 URDF 实现,代码实现更为精简、高效、易读。容易混淆的是Rviz与Gazebo,在此我们着重比较以下二者的区别:
rviz是三维可视化工具,强调把已有的数据可视化显示;
gazebo是三维物理仿真平台,强调的是创建一个虚拟的仿真环境。
rviz需要已有数据。
rviz提供了很多插件,这些插件可以显示图像、模型、路径等信息,但是前提都是这些数据已经以话题、参数的形式发布,rviz做的事情就是订阅这些数据,并完成可视化的渲染,让开发者更容易理解数据的意义。
gazebo不是显示工具,强调的是仿真,它不需要数据,而是创造数据。
我们可以在gazebo中免费创建一个机器人世界,不仅可以仿真机器人的运动功能,还可以仿真机器人的传感器数据。而这些数据就可以放到rviz中显示,所以使用gazebo的时候,经常也会和rviz配合使用。当我们手上没有机器人硬件或实验环境难以搭建时,仿真往往是非常有用的利器。
综上,如果你手上已经有机器人硬件平台,并且在上边可以完成需要的功能,用rviz应该就可以满足开发需求。
如果你手上没有机器人硬件,或者想在仿真环境中做一些算法、应用的测试,gazebo+rviz应该是你需要的。
另外,rviz配合其他功能包也可以建立一个简单的仿真环境,比如rviz+ArbotiX。