ROS术语
主节点(master):负责节点到节点的连接和消息通信,类似于名称服务器(NameServer)。roscore是它的运行命令。主节点使用XML远程过程调用(XMLRPC,XML-Remote Procedure Call)与节点进行通信。当启动ROS时,主节点将获取用户设置的ROS_MASTER_URI变量中列出的URI地址和端口。除非另外设置,默认情况下,URI地址使用当前的本地IP,端口使用11311。
节点(node):是指在ROS中运行的最小处理器单元。在ROS中,建议为一个目的创建一个节点。节点在运行的同时,向主节点注册节点的名称,并且还注册发布者(publisher)、订阅者(subscriber)、服务服务器(service server)、服务客户端(service client)的名称,且注册消息形式、URI地址和端口。基于这些信息,每个节点可以使用话题和服务与其他节点交换消息。
节点使用XMLRPC与主站进行通信,并使用TCP/IP通信系列的XMLRPC或TCPROS5进行节点之间的通信。节点之间的连接请求和响应使用XMLRPC,而消息通信使用
TCPROS,因为它是节点和节点之间的直接通信,与主节点无关。URI地址和端口则使用存储于运行当前节点的计算机上的名为ROS_HOSTNAME的环境变量作为URI地址,并
将端口设置为任意的固有值。
功能包(package):是构成ROS的基本单元。ROS应用程序是以功能包为单位开发的。功能包包括至少一个以上的节点或拥有用于运行其他功能包的节点的配置文件。它还包含功能包所需的所有文件。
元功能包(metapackage):是一个具有共同目的的功能包的集合。例如,导航元功能包包含AMCL、DWA、EKF和map_server等10余个功能包。
消息(message):节点之间通过消息(message)8来发送和接收数据。消息是诸如integer、floatingpoint和boolean等类型的变量。用户还可以使用诸如消息里包括消息的简单数据结构或列举消息的消息数组的结构。使用消息的通信方法包括TCPROS,UDPROS等,根据情况使用单向消息发送/接收方式的话题(topic)和双向消息请求(request)/响应(response)方式的服务(service)。
话题(topic):话题(topic)9就是“故事”。在发布者(publisher)节点关于故事向主节点注册之后,它以消息形式发布关于该故事的广告。希望接收该故事的订阅者(subscriber)节点获得在主节点中以这个话题注册的那个发布者节点的信息。基于这个信息,订阅者节点直接连接到发布者节点,用话题发送和接收消息。
发布与发布者:发布(publish)是指以与话题的内容对应的消息的形式发送数据。为了执行发布,发布者(publisher)节点在主节点上注册自己的话题等多种信息,并向希望订阅的订阅
者节点发送消息。发布者在节点中声明自己是执行发布的个体。单个节点可以成为多个发布者。
订阅与订阅者:订阅是指以与话题内容对应的消息的形式接收数据。为了执行订阅,订阅者节点在主节点上注册自己的话题等多种信息,并从主节点接收那些发布此节点要订阅的话题的发布
者节点的信息。基于这个信息,订阅者节点直接联系发布者节点来接收消息。订阅者在节点中声明自己执行订阅的个体。单个节点可以成为多个订阅者。
服务(service):消息通信是服务客户端(service client)与服务服务器(serviceserver)之间的同步双向消息通信。其中服务客户端请求对应于特定目的任务的服务,而服务服务器则负责服务响应。
服务服务器(service server):是以请求作为输入,以响应作为输出的服务消息通信的服务器。请求和响应都是消息,服务器收到服务请求后,执行指定的服务,并将结果下发给服务客户端。服务服务器用于执行指定命令的节点。
服务客户端(service client):是以请求作为输出并以响应作为输入的服务消息通信的客户端。请求和响应都是消息,并发送服务请求到服务服务器后接收其结果。服务客户端用于传达给定命令并接收结果值的节点。
动作(action):是在需要像服务那样的双向请求的情况下使用的消息通信方式,不同点是在处理请求之后需要很长的响应,并且需要中途反馈值。动作文件也非常类似于服务,目标(goal)和结果(result)对应于请求和响应。此外,还添加了对应于中途的反馈(feedback)。它由一个设置动作目标(goal)的动作客户端(action client)和一个动作服务器(action server),动作服务器根据目标执行动作,并发送反馈和结果。动作客户端和动作服务器之间进行异步双向消息通信。
动作服务器(action server):以从动作客户端接收的目标作为输入并且以结果和反馈值作为输出的消息通信的服务器。在接收到来自客户端的目标值后,负责执行实际的动作。
动作客户端(action client):是以目标作为输出并以从动作服务器接收待结果和反馈值作为输入的消息通信的客户端。它将目标交付给动作服务器,收到结果和反馈,并给出下一个指示或取消目标。
参数:ROS中的参数(parameter):是指节点中使用的参数。可以把它想象成一个Windows程序中的*.ini配置文件。这些参数是默认(default)设置的,可以根据需要从外部读取或写入
参数服务器(parameter server):是指在功能包中使用参数时,注册各参数的服务器。参数服务器也是主节点的一个功能。
catkin:是指ROS的构建系统。ROS的构建系统基本上使用CMake(Cross PlatformMake),并在功能包目录中的CMakeLists.txt文件中描述构建环境。在ROS中,我们将CMake修改成专为ROS定制的catkin构建系统
rosbuild:ROS构建(rosbuild)是在构建catkin构建系统之前使用的构建系统,虽然仍有一些用户可以使用,但这只是为ROS版本兼容性保留的
roscore:roscore是运行ROS主节点的命令。也可以在另一台位于同一个网络内的计算机上运行它。但是,除了支持多roscore的某些特殊情况,roscore在一个网络中只能运行一个。运行ROS时,将使用您在ROS_MASTER_URI变量中列出的URI地址和端口。如果用户没有设置,会使用当前本地IP作为URI地址并使用端口11311
rosrun:是ROS的基本运行命令。它用于在功能包中运行一个节点。节点使用的URI地址将存储在当前运行节点的计算机上的ROS_HOSTNAME环境变量作为URI地址,端口被设置为任意的固有值。
roslaunch:如果rosrun是执行一个节点的命令,那么roslaunch是运行多个节点的概念。该命令允许运行多个确定的节点。其他功能还包括一些专为执行具有诸多选项的节点的ROS命令,比如包括更改功能包参数或节点名称、配置节点命名空间、设置ROS_ROOT和ROS_PACKAGE_PATH以及更改环境变量等。roslaunch使用*.launch文件来设置可执行节点,它基于可扩展标记语言(XML),并提供XML标记形式的多种选项。
bag:用户可以保存ROS中发送和接收的消息的数据,这时用于保存的文件格式称为bag20,是以*.bag作为扩展名。在ROS中,这个功能包可以用来存储信息并在需要时可以回放以前的情况。例如,当使用传感器执行机器人实验时,使用bag将传感器值以消息形式保存。有了这些保存的信息,即使不重复执行之前的实验,也能通过回放保存的bag文件来反复利用当时的传感器值。特别的,如果利用rosbag的记录和回放功能,在开发那些需要反复修改程序的算法的时候会非常有用。
存储库:每一个公开的功能包在该功能包的wiki上指定一个存储库(repository)。存储库是存储功能包的网站的URL地址,并使用源代码管理系统(如svn、hg和git)来管理问题、开发、下载等。许多当前可用的ROS功能包将github用作存储库。如果您对每个功能包的源代码内容感兴趣,则可以在相应的存储库中进行查阅。
状态图:上面描述的节点、话题、发布者和订阅者之间关系可以通过状态图(graph)直观地表示。它是当前正在运行的消息通信的图形表示。但不能为一次性服务创建状态图。执行它是通过运行rqt_graph功能包的rqt_graph节点完成的。有两种执行命令:rqt_graph和rosrun rqt_graph rqt_graph。
名称:节点、参数、话题和服务都有名称(name)。当使用主节点的参数、话题和服务时,向主节点注册该名称并根据名称进行搜索,然后发送消息。此外,名称非常灵活,因为它们可以在运行时被更改。另外,对于一个节点、参数、话题和服务,也能给其设定多个不同的名称。这种取名规则使得ROS适用于大型项目和复杂系统。
ROS总体设计---一个目标
提高机器人研发中的软件复用率
ROS总体设计---五个特点
(1)、点对点的设计
节点单元
分布式网络
RPC+TCP/UDP通信系统
适合多机协同
(2)、多语言支持
支持Python、C+、Java等编程语言
语言无关的接口
(3)、架构精简、集成度高
每个功能节点可以单独编译
集成众多开源项目 如OpenCV PCL OpenRAV OpenNI
接口统一、提高软件复用性
(4)、组件化工具包丰富
3D可视化工具---rviz
物理仿真环境---gazebo
数据记录工具---rosbag
Qt工具箱---rqt_*
(5)、免费并且开源
BSD许可,可修改、可复用、可商用
软件包数量指数级增加,良好的生态系统
ROS总体设计---四位一体
ROS系统实现---三个层次
开源社区:ROS资源是如何分布式管理的
文件系统:程序文件是如何组织和构建的
计算图:描述程序是如何运行的
ROS系统实现---计算图
(1)节点(Node)---软件模块
(2)节点管理器(ROS Master)---控制中心,提供参数管理
(3)话题(Topic)---异步通信机制,传输消息(Message)
(4)服务(Service)---同步通信机制,传输请求/应对数据
ROS系统实现---话题通信机制
(1)Talker注册
(2)Listener注册
(3)ROS Master进行信息匹配
(4)Listener发送连接请求
(5)Talker确认连接请求
(6)建立网络连接
(7)Talker向Listener发布数据
ROS系统实现---服务通信机制
(1)Talker注册
(2)Listener注册
(3)ROS Master进行信息匹配
(4)建立网络连接
(5)Talker向Listener发布服务应答数据
ROS系统实现---参数通信机制 通过RPC协议
(1)Talker设置变量
(2)Listener查询参数值
(3)ROS Master向Listener发送参数值
ROS系统实现---话题与服务的区别
ROS系统实现---文件系统
(1)功能包清单(Package mainfest):记录功能包的基本信息,包括作者信息、许可信息、依赖选项、编译标志等
(2)元功能包(Meta Packages):组织多个用于同一目的功能包
(3)元功能包清单(Meta Packages):类似于功能包清单,不同之处在于元功能包清单中可能会包含运行时需要依赖的功能包或者声明一些引用的标签。
(4)消息类型(Message):消息是ROS节点之间发布/订阅的通信信息,可以使用ROS系统提供的消息类型,也可以使用.msg文件在功能包的msg文件夹下自定义需要的消息类型。
(5)服务类型(Service):服务类型定义了ROS服务器/客户端通信模式下的请求与应答数据类型,可以使用ROS系统提供的服务类型,也可以使用.srv文件在功能包的srv文件夹中进行定义。
(6)代码(Code):放置功能包节点源代码的文件夹
ROS初次实践---版本选择
ROS Kinetic Kame
ROS初次实践---安装方法
(1)添加ROS源:
sudo -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main">/etc/apt/sources.list.d/ros-latest.list'
(2)添加秘钥:
sudo apt-get adv --keyserver hkp://ha.pool.sks-keyserver.net:80 --recv-key 421C365BD9FF1F717815A3895523BAEEB01FA116
(3)安装ROS:
sudo apt-get update
sudo apt-get install ros-kinetic-desktop-full
(4)初始化rosdep:
sudo rosdep init
rosdep update
(5)设置环境变量:
echo "source /opt/ros/kinetic/setup.bash">>~/.bashrc
source ~/.bashrc
(6)安装rosinstall:
sudo apt-get install python-rosinstall python-rosinstall-generator python-wstool build-essential
安装目录,默认在/opt/ros路径下
使用roscore命令启动ROS Master
roscore
rosrun turtlesim turtlesim_node
通过Docker镜像使用ROS
1.安装Docker
sudo apt-get install docker.io
2.获取和使用ROS Docker镜像和容器
所有ROS Docker镜像都在官方网站的ROS镜像仓库中列出,网址为https://hub.docker.com/_/ros/。使用下面的命令获取ROS容器镜像:
docker pull ros
有可能出现错误
可以通过更新系统或尝试将用户添加到docker组以解决此问题:
sudo usermod -a -G docker $(whoami)
使用下面的命令及对应的标签获取ROS Kinetic发行版:
docker pull ros:kinetic-robot
容器下载完成后,可以使用以下命令以交互方式运行:
docker run -it ros
必须在容器内设置ROS环境,以便使用ROS。也就是说,必须运行下面的命令:
source /opt/ros/kinetic/setup.bash
Docker容器可以通过docker stop命令从其他终端停止,也可以使用docker rm进行删除
ROS初次实践---命令工具
ROS初次实践---第一个ROS例程
(1)启动ROS Master roscore
(2)启动小海龟仿真器 rosrun turtlesim turtlesim_node
(3)启动海龟控制节点 rosrun turtlesim turtle_teleop_key
ROS框架
消息通信
节点之间的消息通信,分为3种:
1.单向消息发送/接收方式的话题(topic)
2.双向消息请求/响应方式的服务(service)
3.双向消息目标(goal)/结果(result)/反馈(feedback)方式的动作
另外,节点中使用的参数可以从外部进行修改
话题消息通信是指发送信息的发布者和接收信息的订阅者以话题消息的形式发送和接收信息。希望接收话题的订阅者节点接收的是与在主节点中注册的话题名称对应的发布者节点的信息。基于这个信息,订阅者节点直接连接到发布者节点来发送和接。
收消息。
ros::NodeHandle Class
常用成员函数
//创建话题的publisher
ros::Publisher advertise(const string &topic,uint32_t queue_size);
//创建话题的Subscribe
ros::Subscribe subscribe(const string &topic,uint32_t queue_size,void(*)(M));
//创建服务的server
ros::ServiceServer advertiseService(const string &service,bool(*srv_func)(Mreq &,Mres &));
//创建服务的Client
ros::ServiceClient serviceClient(const string $service_name,bool persistent=false);
//查询某个参数的值
bool getParam(const string &key,void &val);
//给参数赋值
bool setparam(const string &key,void val);
ros::Master Namespace
常用函数
bool check();//检查master是否启动
const string& getHost();//返回master所处的hostname
bool getNodes(V_string &nodes);//从master返回已知的node名称列表
bool getTopics(V_TopicInfo &topics);//返回所以正在被发布的topic列表
bool getURI();//返回到master的URI地址
uint32_t getPort();//返回master运行在的端口号
ros::this_node Namespace
常用函数
void getAdvertisedTopic(V_string &topics); //返回本node发布的topic
const string &getName(); //返回当前node的名称
const string &getNamespace(); //返回当前node的命名空间
void getSubscribedTopic(V_string &topic ); //返回当前node订阅的topic
ros::service Namespace
常用函数
//调用一个RPC服务
bool call(const string &service,Service &service);
//创建一个服务的client
ServiceClient createClient(const string &service_name,bool persistent=false,const M_string &header_values=M_string());
//确认服务可调用
bool exists(const string &service_name,bool print_failure_reason);
//等待一个服务,直到它可以调用
bool waitForService(const string &service_name,int32_t timeout);
ros::name Namespace
常用函数
string append(const std::string &left,const std::string &right);//追加名称
string clean(const string &name);//清除图资源名称:删去双斜线、结尾斜线
const M_string &getRemappings();//返回重映射remapping
string remap(const string &name);//对名称重映射
string resolve(const string &name,bool remap=true);//解析出名称的全名
bool validate(const string &name,string &error);//验证名称
topic_demo
功能描述:两个node,一个发布模拟的GPS消息(格式为自定义,包括坐标和工作状态),另一个接受并处理该信息
(计算到原点的距离)
步骤:
1.package
cd ~/catkin_ws/src
catkin_create_pkg topic_demo roscpp rospy std_msgs
2.msg
cd topic_demo/
mkdir msg
cd msg
vi gps.msg
gps.msg
float32 x
float32 y
string state
对gps.msg进行编译 catkin make编译后生成 ~/catkin_ws/devel/include/topic_demo/gps.h
3.talker.cpp
#include <ros/ros.h>
#include <topic_demo/gps.h>
int main(int argc,char** argv)
{
ros::init(argc,argv,"talker");//解析参数 命名节点
ros::NodeHandle nh; //创建句柄 实例化node
topic_demo::gps msg; //创建gps消息
msg.x=1.0;
msg.y=1.0;
msg.state="working";
ros::Publisher pub = nh.advertise<topic_demo::gps>("gps_info",1);//创建publisher
ros::Rate loop_rate(1.0); //定义发布的频率,1HZ
while (ros::ok()) //循环发布msg
{
msg.x=1.03*msg.x;
msg.y=1.01*msg.y;
ROS_INFO("talker:GPS:x=%f,y=%f",msg.x,msg.y);//输出当前的msg
pub.publish(msg); //发布消息
loop_rate.sleep();//根据定义的发布评率,sleep
}
return 0;
}
4.listener.cpp
#include <ros/ros.h>
void gpsCallback(const topic_demo::gps::ConstPtr &msg)
{
std_msgs::Float32 distance;
distance.data = sqrt(pow(msg->x,2),pow(msg->y,2));
ROS_INFO("Listener:Distance to origin = %f,state=%s",distance.data,msg->state.c_str());
}
int main(int argc,char** argv)
{
ros::init();
ros::NodeHandle n;
ros::Subscribe sub = n.subscribe("gps_info",1,gpsCallback);//创建subscriber topic名称 消息队列 回调函数(指针)
ros::spin();//反复调用当前可触发的回调函数,阻塞
return 0;
}
5.CMakeList.txt&package.xml
cmake_
SLAM:Simutaneous Localization And Mapping
Map
Topic:/map
Type:nav_msgs/OccupancyGrid.msg
Gmapping Topic
Gmapping Service
Service:/dynamic_map
Type:nav_msgs/GetMap
nav_msgs/GetMap.srv
#Get the map as a nav_msgs/OccupancyGrid
---
nav_msgs/OccupancyGrid map
Gmapping Param
~inverted_laser(string,default: "false" ) #雷达是否反向放置
~throttle_scans(int,default:1) #每多少次scan才处理一次
~base_frame(string,default: "base_link" ) #底盘坐标系
~map_frame(string,default: "map" ) #机器人坐标系
~odom_frame(string,default: "odom" ) #里程计坐标系
~map_update_interval(float,default:5.0) #更新地图周期(秒)
~particles(int,default:30) #粒子数
~transform_publish_period(float,default:0.05) #tf发布周期
...
Karto SLAM
Move_base
全局规划 局部规划 处理异常行为
costmap
用于路径规划 两张 2维 多层
static layer (map)
静态
obstacle layer
动态 支持3D点云的投影
inflation layer
膨胀