Week 1 - ROS通信初步
ROS是什么
ROS是一个集成了许多工具和库的机器人操作框架,以节点之间的通信实现对数据的处理和硬件的操控。
配置ROS的工作环境
Windows上有用choco分发的ROS2,不过目前功能不算完善,所以关于ROS的开发工作一般在Linux系列系统上进行,这里我们选用20.04的Ubuntu来配置工作环境。
参考AutoLabor上的教程,配置主要有以下步骤。
- 设置安装源
1
sudo sh -c '. /etc/lsb-release && echo "deb http://mirrors.tuna.tsinghua.edu.cn/ros/ubuntu/ `lsb_release -cs` main" > /etc/apt/sources.list.d/ros-latest.list'
- 设置key
1
sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654
- 安装
1
2sudo apt update
sudo apt install ros-noetic-desktop-full - 配置环境变量其中
1
2echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc
source ~/.bashrc.bashrc
是Ubuntu系统根目录下的记录环境变量的文件,以后我们自己编译了什么项目也可以把路径放在这里。 - 安装构建依赖
1
sudo apt install python3-rosdep python3-rosinstall python3-rosinstall-generator python3-wstool build-essential
- 初始化rosdep
1
2sudo rosdep init
rosdep update
HelloWorld
在ROS里实现HelloWorld,首先需要我们构造一个节点,然后让该节点在日志中将HelloWorld作为信息输出。
搭建工作环境
要搭建工作环境,首先需要在工作区执行
1 | catkin_make |
这个命令的执行需要文件夹下存在src
目录,该目录存放我们的工程文件。
之后要编译其中的工作文件我们也需要执行同样的命令。
完成命令后,会额外生成./bin
与./devel
文件夹,与./src/CMakeLists.txt
./bin
中会存放生成的构建文件./devel
中会存放生成的执行脚本与一些头文件
创建工具包
要开始编写节点,我们需要先创建工具包,进入./src
目录,并执行
1 | catkin_create_pkg 包名 roscpp rospy std_msgs |
包名
的命名不要携带任何大写字母、下划线与连接线,用纯小写字母,这是一种命名规范roscpp
或者rospy
是C++语言或Python语言的基础工具包,std_msgs
是标准消息库,之后的通信会用到。
配置CMakeLists.txt
将add_executable()
和target_link_libraries()
取消注释,表明本次构建生成可执行文件。
编写项目
编写项目的流程就我目前总结如下:
- 修改工具包下
packages.xml
,添加所需依赖 - 依据需求修改
CMakeLists.txt
,设置编译过程 - 如果要生成例如
msg
和srv
这种依赖,那么先编译一遍 - 配置工具包和依赖完成后,写代码。
- 完成节点代码后编译
- 启动节点测试
为了实现HelloWorld,我们需要编写如下代码
1 |
|
尤其值得注意的是,#include "ros/ros.h"
这一行,为了让VSCode找到ros的头文件,我们要编辑includePath
设置,一般来说在ros的默认安装路径下头文件在/opt/ros/noetic/include/**
(最后那个**指包含所有子目录)
进行ros编程,最重要的就是节点,我们首先初始化并声明自己这个节点,然后再下一步输出日志。
int argc, char *argv[]
是运行该节点时的一些基本参数,argc
代表参数数量,argv
是参数列表
没有额外参数传入时,argv[0]
为文件路径,argv[1]
为节点名称,argv[2]
为日志路径,argc
为3
。
有额外参数时,argv[1]
是第一个额外参数,argv[2]
等等以此类推,argc
为参数数量加上3
。
启动节点测试
首先启动ROS内核
1 | roscore |
然后在工作区内启动节点
1 | source ./devel/setup.bash |
节点通信的三类模型
参数服务器模型
ROSMaster负责储存一系列参数,发布者修改其中的参数,订阅者可以获取其中的参数。
工程文件详见param
文件夹,以下提出几个要点:
- 服务器使用
setParam()
设置并准备发布参数,hasParam()
检测参数存在性,getParam()
以获取参数值。 - 该方法并不高效,不要把这个玩意当寄存器用。
服务通信模型
ROSMaster负责让发布者与订阅者建立连接,发布者接受来自订阅者的数据请求,并相应回给订阅者处理后的信息。
工程文件详见srv
文件夹,以下提出几个要点:
- 为了明确发布者和订阅者发送的数据类型与数目,需要提前建立
srv
文件夹并准备.srv
描述文件 .srv
文件中---
上方的是订阅者请求信息,下方是发布者回应信息CMakeLists.txt
中,应当将add_service_files()
与generate_messages()
方法打开,并添加message_generation
作为第三方库到find_package()
中。package.xml
中,应当添加如下引用1
2<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>- 调用订阅者节点时,在这个实例中,应当在
rosrun
指令后添加参数,参数会被argv
储存 - 用
waitForService()
方法可以在节点没启动时阻塞进程
话题通信模型
ROSMaster负责让发布者与订阅者建立连接,发布者发布消息,订阅者接收信息。
工程文件详见msg
文件夹,其使用了.msg
文件自定义传输数据,以下提出几个要点:
- 如果要自定义传输数据的结构,需要提前建立
msg
文件夹并准备.msg
描述文件 .msg
文件中一行一个变量定义CMakeLists.txt
中,应当将add_message_files()
与generate_messages()
方法打开,并添加message_generation
作为第三方库到find_package()
中。package.xml
中,应当添加如下引用1
2<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>
其它事项
1 | rqt_graph |
这个命令可以查看所有的节点状态与它们之间的关系。
创建工具包时使用catkin_create_pkg
命令需在./src
资源文件夹内进行。
编写msg
文件或者srv
文件时,int
类型定义为int32
,long long
为int64
,double
为float64
,记得查表。