之前已经接触过一些ROS的使用,但是还没有系统地学习过,因此在此记录一下学习的笔记。学习ROS首先必须参考ROS wiki及ROS Answers,另外国内“古月居”的博客和“东方赤龙”的博客都可以参考学习,古月居的书《ROS机器人开发实践》也不错,可以用来系统的学习。不过,需知道ROS本身只是一个方便大家开发的工具罢了。
1. 初识ROS
分布式网络,TCP/IP,模块间松耦合连接
三种通信机制:
1.基于发布/订阅topic通信(异步)
- talker注册
- listener注册
- ROS master进行信息匹配
- listener发送连接请求
- talker确认连接请求
- listener尝试与talker建立网络连接
- talker向listener发布数据
注意,节点建立连接后,可以关掉ROS master,节点间数据传输不受影响,但其他节点也无法加入这两个节点间的网络。
2.基于客户端/服务器service通信(同步)
带有应答,减少了listener与talker间的RPC通信。底层协议和topic通信一样,用的都是ROSTCP/ROSUDP。
只允许一个节点提供指定命名的服务(一对多),实时性比topic强。
3.基于远程过程调用(RPC)的参数服务器
不涉及TCP/UDP通信。
参数类似ROS中的全局变量,包含key和value,由ROS master进行管理。
需注意有时需要动态参数配置来通知listener参数已被更新。
topic通信适用于不断更新、含较少逻辑处理的数据通信;service通信适用于数据量较少但有逻辑处理的数据交换。
2. ROS架构
分为三层:
- OS层。基于linux
- 中间层。提供通信机制及一些库
- 应用层。各功能包内模块以节点为单位
3. ROS基础
3.1 创建工作空间和功能包
mkdir -p ~/catkin_ws/src
# 在工作空间根目录编译,编译后自动出现build和devel文件夹及几个脚本文件,用于设置环境变量等
cd ~/catkin_ws/
catkin_make
# 运行脚本文件使其生效
source devel/setup.bash
# 查看环境变量是否生效
echo $ROS_PACKAGE_PATH
# 如果没添加上使用sudo gedit ~/.bashrc打开文件手动添加。或者在终端使用下面命令直接添加。
# 这种方式对所有终端都有效,而source只对当前终端有效!
echo "source ~/catkin_ws/devel/setup.bash">> ~/.bashrc
source ~/.bashrc
# 进入代码空间,创建自己的功能包。一般都会依赖roscpp,rospy,std_msgs这几个功能包
# 不过也可以不用现在添加,后续用到具体的依赖时,再在CMakeLists中直接加上即可。
# 你也可以直接去github下载别人写好的功能包,就不用自己创建啦。
# 创建完成后,代码空间src中会生产一个叫my_package的功能包,其中已经包含package.xml和CMakeLists.txt文件。
# 在后续写代码时,就可以把源码放进功能包src文件夹中,然后写相应的CMakeLists.txt就可以了。具体见下面CLion教程。
cd ~/catkin_ws/src
catkin_create_pkg my_package roscpp rospy std_msgs
3.2 工作空间的覆盖
# ROS中为解决同名功能包问题,存在覆盖机制。即$ROS_PACKAGE_PATH中记录的环境变量,最前面覆盖最后面的。
# 创建多个同名功能包时,需要注意这点!
# rospack 查找功能包所放置的工作空间
rospack find roscpp
3.3 使用IDE运行及调试ROS程序
这个是非常重要的一点!否则后面不管是自己写ros程序还是用别人开源的程序,调试起来会很麻烦。
ROS支持许多IDE开发,具体可以看wiki上的介绍。CLion是一个个人觉得非常好用的跨平台c++IDE。搭建CLion开发环境后可以利用CLion运行和调试ros程序,十分方便,具体见CLion官方教程
其中需要注意的是,每次必须从终端利用bash打开CLion;或者要改一个桌面快捷方式文件,使其每次通过bash启动,网上可以搜到解决方案。
另外,还可以配置下编译路径。CLion默认在cmake-build-debug或cmake-build-release文件夹保存编译文件。可以通过File|Settings(Ctrl+Alt+S)|Build, Execution, Deployment|CMake改一下:
1.Generation path改为/home/name/catkin_ws/build
2.CMake options加上 -DCATKIN_DEVEL_PREFIX:PATH=/home/name/catkin_ws/devel
3.4 创建Publisher和Subscriber
这也是一个非常重要的一点!因为做slam会经常用到订阅传感器发布的话题,然后获取各种传感器数据并在程序中处理后,生成位姿与地图,最终把结果按相应规定的数据格式发布出去。
基于C++写一个ROS程序,深入理解发布和订阅机制:
http://wiki.ros.org/ROS/Tutorials/WritingPublisherSubscriber%28c%2B%2B%29
3.5 自定义话题消息
ROS的元功能包common_msgs提供了许多不同消息类型的功能包,如std_msgs、geometry_msgs、sensor_msgs等。当不能满足自己程序的需求时,可以在项目下新建msg文件夹,并将自定义的消息类型文件.msg放于其中。然后更改package.xml和CMakeLists.txt文件即可。
话题消息编译与编程语言无关。
3.6 创建Server和Client
类似可以自定义消息,你也可以将自定义服务数据.srv放置于新建的srv文件夹。
创建Server过程类似创建Subscriber,而创建Client类似创建Publisher。
3.7 分布式多机通信
非常常用,第五章会用到
需要配置IP地址和设置ROS_MASTER_URI
4. ROS中常用组件
4.1 launch启动文件
利用xml文件同时启动和配置多节点,避免了每次打开多个终端运行多个节点。
重要的节点属性包括name/pkg/type/args/output等,其中:
<name>
定义节点运行的名称,将覆盖节点中init()赋予节点的名称<pkg>
定义节点所在功能包名称<type>
定义节点可执行文件名<args>
定义节点运行参数,可以有多个<output>
若值为screen表示节点标准输出到终端屏幕,默认输出为日志文档
参数设置:
<param>
类似变量声明<rosparam>
直接加载整个yaml文件<arg>
类似launch文件内部的局部变量,仅限内部使用,与节点无关
这里需要注意一个小问题。比如我的程序需要1个输入参数(即argc=2),在使用launch文件后,程序参数个数变多了(即argc>2)。比如这是我的launch文件,可以看到我的程序需要1个输入参数:
<launch>
<node
name="rgbdslam" pkg="rgbdslam" type="run_vo" args="$(find rgbdslam)/config/default.yaml"
output="screen"
/>
</launch>
但是,运行后程序的实际argv打印到屏幕如下,多了两个参数。不过这个小问题影响不大,了解即可:
/home/gjh/catkin_ws/src/rgbdslam/bin/run_vo
/home/gjh/catkin_ws/src/rgbdslam/config/default.yaml
__name:=rgbdslam
__log:=/home/gjh/.ros/log/e840c676-1bca-11e9-b271-000c290958e7/rgbdslam-2.log
重映射:类似c++别名机制,如:
<remap from="/turtlebot/cmd_vel" to="/cmd_vel" />
另外,也可以使用终端完成重映射,如之前运行lsd-slam时就使用过这种方法:
rosrun lsd_slam_core live_slam image:=/image_raw camera_info:=/camera_info
嵌套复用。其中使用find命令查找当前包的路径,如:
<include file="$(find mypackage)/launch/other.launch">
在launch中直接启动master,参数还可以为restart或no:
<master auto="start"/>
4.2 TF坐标变换
# 一些TF工具
# 1.查看指定坐标系之间变换关系,即平移和旋转
rosrun tf tf_echo <source_frame> <target_frame>
# 2.显示TF树信息,并保存为pdf
rosrun tf view_frames
# 3.其他
tf_monitor
static_transform_publisher
通过创建TF广播器和TF监听器,实现乌龟跟随运动
4.3 Qt工具箱
日志输出工具 rqt_console
计算图可视化工具 rqt_graph
数据绘图工具 rqt_plot
参数动态配置工具 rqt_reconfigure
4.4 rviz可视化平台
配置好rviz后,可以在file|save config as保存.rviz文件。然后使用-d参数加载配置文件,从而可以避免每次重新配置:
rosrun rviz rviz -d <path>/rvizfile.rviz
# for example
rosrun rviz rviz -d `rospack find turtle_tf`/rviz/rvizfile.rviz
或者还可以把这一步写进launch文件中,更加方便!
4.5 rosbag数据记录与回放
# 查看bag文件信息,时长duration,是否压缩等
rosbag info <your bagfile>
# 解压缩
rosbag decompress <your bagfile>
5.机器人平台搭建
机器人组成:
- 执行机构。类似“手脚”
- 驱动机构。类似“肌肉和筋络”。驱动板:电源子系统、电机驱动子系统、传感器接口
- 传感系统。类似“感官”。内部传感器(里程计、陀螺仪);外部传感器(摄像头、激光)
- 控制系统。类似“大脑”。处理器(使用树莓派/PC等)、算法,与ROS相关较大
基于树莓派控制系统
- 使用单处理器。直接使用PC+ROS,通过usb通信,但无法远程监控。
- 使用多处理器(推荐)。两台PC/PC+嵌入式,无线网络通信。
例子:利用PC控制MRobot移动,并配备传感器。
嵌入式完成本地运动控制及传感器数据采集,远端PC完成远程监控及复杂功能计算。
6.机器人建模与仿真
6.1 URDF统一机器人描述格式
<link>
机器人刚体部分外观和物理属性
<joint>
连接两个刚体link,6种类型
<robot>
最顶层标签,包含一系列link和joint
<gazebo>
不是必需,只在gazebo仿真时加入
6.2 创建机器人URDF模型
# 1.编写urdf
# 2.检查xml格式
check_urdf mrobot_chasssis.urdf
# 3.生成模型的整体结构图
urdf_to_graphiz mrobot_chasssis.urdf
# 4.rviz中可视化
6.3 xacro优化urdf
原始urdf冗长重复,xacro进行改进。
可以使用常量定义、调用数学公式、使用宏定义(类似函数)以达到精简目的。
6.4 添加传感器模型
6.5 Gazebo仿真
rosrun gazebo_ros gazebo
如果没有真实机器人,则需仿真。仿真前,需构建仿真环境。两种方式:
- 直接insert模型. 需连外网,或把模型提前下载到指定目录下;
- Building Editor. 在Edit菜单中