Rviz是一款机器人开发过程中的数据可视化软件,用于可视化机器人模型、传感器信息、环境信息等等。
Rviz的核心框架是基于Qt可视化工具打造的一个开放式平台,官方出厂就自带了很多机器人常用的可视化显示插件,只要我们按照ROS中的消息发布对应的话题,就可以看到图形化的效果了。如果我们对显示的效果不满意,或者想添加某些新的显示项,也可以在Rviz这个平台中,开发更多可视化效果,方便打造我们自己的上位机。
Rviz是一款三维可视化工具,可以很好地兼容基于ROS软件框架的机器人平台。
在rviz中,可以使用可扩展标记语言XML对机器人、周围物体等任何实物进行尺寸、质量、位置、材质、关节等属性的描述,并且在界面中呈现出来
同时,rviz还可以通过图形化的方式,实时显示机器人传感器的信息、机器人的运动状态、周围环境的变化等信息。
总而言之,rviz通过机器人模型参数、机器人发布的传感信息等数据,为用户进行所有可监测信息的图形化显示。用户和开发者也可以在rviz的控制界面下,通过按钮、滑动条、数值等方式,控制机器人的行为。
只要有数据,它就可以可视化。
通过在命令行窗口输入以下指令可以打开rviz:
ros2 run rviz2 rviz2
打开rviz后,可以在左侧栏内添加部件(官方提供了包括雷达、摄像机等诸多部件模板),并为那个部件设置订阅的话题,进行可视化。
下面是一个示例:
先定义一个摄像机仿真:
<?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"> <!--相机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" /> <!--box是一个立方体,后面参数是尺寸-->
</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"> <!--调用gazebo相机渲染插件的部分-->
<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">
<!--调用gazebo中的插件实现相机功能-->
<ros>
<!-- <namespace>stereo</namespace> -->
<remapping>~/image_raw:=image_raw</remapping>
<!--通过话题发布数据-->
<remapping>~/camera_info:=camera_info</remapping>
</ros>
<camera_name>${prefix}</camera_name> <!--相机名字-->
<frame_name>${prefix}_link</frame_name>
<!--坐标系,与连杆名字一样-->
<hack_baseline>0.2</hack_baseline>
</plugin>
</sensor>
</gazebo>
</xacro:macro>
</robot>
该文件在下面的总文件里被调用:
<?xml version="1.0"?>
<robot name="mbot" xmlns:xacro="http://www.ros.org/wiki/xacro">
<!---->
<xacro:include filename="$(find learning_gazebo)/urdf/mbot_base_gazebo.xacro" />
<!--引用机器人模型文件-->
<xacro:include filename="$(find learning_gazebo)/urdf/sensors/camera_gazebo.xacro" />
<!--引用相机模型文件-->
<!--三个常量表示相机与机器人底盘的关系-->
<xacro:property name="camera_offset_x" value="0.17" />
<xacro:property name="camera_offset_y" value="0" />
<xacro:property name="camera_offset_z" value="0.10" />
<!-- Camera -->
<joint name="camera_joint" type="fixed"> <!--连接相机和底盘的joint-->
<origin xyz="${camera_offset_x} ${camera_offset_y} ${camera_offset_z}" rpy="0 0 0" />
<parent link="base_link"/>
<child link="camera_link"/>
</joint>
<xacro:usb_camera prefix="camera"/> <!--调用相机宏定义-->
<xacro:mbot_base_gazebo/> <!--调用底盘宏定义-->
</robot>
使用上一期的两条指令启动仿真和小车控制:
ros2 launch learning_gazebo load_urdf_into_gazebo.launch.py
ros2 run teleop_twist_keyboard teleop_twist_keyboard
再启动rviz:
ros2 run rviz2 rviz2
再到rviz左侧栏add一个新的部件“Image”,并双击其topic值设置为“/camera/image_raw”。
这时候就能在rviz里看到小车摄像头看到的东西了。同时,通过按键控制小车移动,可以看到图像也会跟随变换。
进一步,还可以进行三维相机仿真与可视化。
三维相机使用的Gazebo插件也是libgazebo_ros_camera.so,配置的xacro文件如下:
<gazebo reference="${prefix}_link">
<sensor type="depth" name="${prefix}"> <!--相机类型是“depth”,一个深度相机-->
<always_on>true</always_on>
<update_rate>15.0</update_rate> <!--更新频率(赫兹),大部分设置和普通相机一样-->
<pose>0 0 0 0 0 0</pose>
<camera name="kinect">
<horizontal_fov>${60.0*M_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="${prefix}_controller" filename="libgazebo_ros_camera.so">
<ros>
<!-- <namespace>${prefix}</namespace> --> <!--传输各种数据的话题及其重定向-->
<remapping>${prefix}/image_raw:=rgb/image_raw</remapping> <!--彩色图像话题-->
<remapping>${prefix}/image_depth:=depth/image_raw</remapping> <!--深度话题-->
<remapping>${prefix}/camera_info:=rgb/camera_info</remapping>
<remapping>${prefix}/camera_info_depth:=depth/camera_info</remapping>
<remapping>${prefix}/points:=depth/points</remapping>
</ros>
<camera_name>${prefix}</camera_name>
<frame_name>${prefix}_frame_optical</frame_name> <!--kinect本身坐标系作参考系-->
<hack_baseline>0.07</hack_baseline>
<min_depth>0.001</min_depth>
<max_depth>300.0</max_depth>
</plugin>
</sensor>
</gazebo>
运行它的axcro文件也基本和普通相机没什么区别,修改一下配置文件为新文件和一些设置参数即可。
<?xml version="1.0"?>
<robot name="mbot" xmlns:xacro="http://www.ros.org/wiki/xacro">
<xacro:include filename="$(find learning_gazebo)/urdf/mbot_base_gazebo.xacro" />
<xacro:include filename="$(find learning_gazebo)/urdf/sensors/kinect_gazebo.xacro" />
<!--kinect-->
<xacro:property name="kinect_offset_x" value="0.15" />
<xacro:property name="kinect_offset_y" value="0" />
<xacro:property name="kinect_offset_z" value="0.11" />
<!-- kinect -->
<joint name="kinect_joint" type="fixed"> <!--安装kinect的joint-->
<origin xyz="${kinect_offset_x} ${kinect_offset_y} ${kinect_offset_z}" rpy="0 0 0" />
<parent link="base_link"/>
<child link="kinect_link"/>
</joint>
<xacro:kinect_camera prefix="kinect"/>
<xacro:mbot_base_gazebo/> <!--两个宏定义-->
</robot>
这个需要使用点云数据可视化。
先用之前同样的命令打开rviz,此处不再重复。
同样的流程,点击Add,添加PointCloud2,设置订阅的点云话题,还要配置Rviz的参考系是odom,就可以看到点云数据啦,每一个点都是由xyz位置和rgb颜色组成。
除了摄像头和三维相机,激光雷达也是很多移动机器人常备的传感器。
雷达使用的Gazebo插件是libgazebo_ros_ray_sensor.so,配置方法如下:
<gazebo reference="${prefix}_link">
<sensor type="ray" name="rplidar"> <!--类型为红外-->
<update_rate>20</update_rate> <!--更新频率-->
<ray>
<scan>
<horizontal>
<samples>360</samples> <!--采集范围:360度-->
<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_ray_sensor.so">
<ros>
<namespace>/</namespace>
<remapping>~/out:=scan</remapping> <!--数据传输的话题-->
</ros>
<output_type>sensor_msgs/LaserScan</output_type> <!--消息类型-->
</plugin>
</sensor>
</gazebo>
使用以下文件包含它:
<?xml version="1.0"?>
<robot name="mbot" xmlns:xacro="http://www.ros.org/wiki/xacro">
<xacro:include filename="$(find learning_gazebo)/urdf/mbot_base_gazebo.xacro" />
<xacro:include filename="$(find learning_gazebo)/urdf/sensors/lidar_gazebo.xacro" />
<xacro:property name="lidar_offset_x" value="0" />
<xacro:property name="lidar_offset_y" value="0" />
<xacro:property name="lidar_offset_z" value="0.105" />
<!-- lidar -->
<joint name="lidar_joint" type="fixed">
<origin xyz="${lidar_offset_x} ${lidar_offset_y} ${lidar_offset_z}" rpy="0 0 0" />
<parent link="base_link"/>
<child link="laser_link"/>
</joint>
<xacro:rplidar prefix="laser"/>
<xacro:mbot_base_gazebo/>
</robot>
运行:
ros2 launch learning_gazebo load_mbot_laser_into_gazebo.launch.py
同时打开rviz,点击Add,选择Laserscan,然后配置订阅的话题名,rviz的固定坐标系依然是odom,此时就可以看到激光点啦。