ROS编程基础

概述

本文主要内容为关于机器人操作系统(Robot Operation System)编程基础内容,以简单概念讲述加上实例操作结合,适合初学者入门学习。

本文的学习目标如下:

  1. 通过实例操作掌握ROS编程的基本规则。
  2. 熟悉ROS常用的工具包以及使用方法。
  3. 创建自定义的工具包。

1.ROS通信机制

通常来说,一个移动机器人是多进程协同工作的,除了少部分进程可以独立完成工作,其他进程都需要进程间的数据交互,因此进程间的通信机制是构建复杂机器人项目的基础。

ROS编程基础_第1张图片

图1 ROS进程通信机制示意图

1.1.节点(Node)

在ROS的世界里,最小的进程单元就是节点(Node)。一般情况下,一个节点负责机器人的某一个单独模块。一个软件包里有多个执行文件,通常为C++编译生成的可执行文件或者Python脚本,可执行文件在运行之后就变成了一个进程(Process),这个进程即为ROS中的节点。

1.2.节点管理器(Master)

节点管理器在整个构架里相当于节点管理中心,管理者各个节点,管理着各个节点(Node)。节点在启动时,首先启动需要在Master处进行注册,之后Master会将该Node纳入到整个ROS程序当中。Node之间的通信也是通过Master进行连线。当ROS程序启动时,首先启动Master,再由Master依次启动Node。在Node建立起连接以后,Master的任务就完成了,此时如果关闭Master,已运行的Node之间的通信还可以继续进行。下面是Node和Master相关命令:    

roscore                                           //启动ros Master

rosrun[pkg_name] [node_name]                      //启动一个aiqiyi

rosnode list                                      //查看当前运行的node信息

rosnode info[node_name]                           //显示node的详细信息

rosnode kill [node_name]                          //结束node

roslaunch[pkg_name] [file_name.launch]            //启动master和多个node

1.3.ROS通信方式

  1. Topic话题模式。
  2. Service服务模式。
  3. Parameter Service(参数服务器)。
  4. Actionlib(动作库)。 

1.4.Topic

Topic是常用的ROS通信方式。对于实时性、周期性的消息,使用Topic模式来传输是最佳的选择。Topic是一种点对点的单向通信方式,这里的“点”指的是节点Node。Topic要经历下面的初始化过程,首先Publisher发布节点和Subscriber在节点管理器Master进行注册;然后Publisher会发布Topic话题,Subscriber在节点管理器Master的指挥下会订阅该话题,从而建立起节点与节点之间的联系。

ROS编程基础_第2张图片

图3 Topic通信示意图

1.4.1.Topic话题通信实例

       主要通过通知小海龟运动的实例介绍Topic话题通信中的Publisher。采用C++实现程序编写、编译及控制,具体操作如下:

1.打开终端输入以下创建名为learning_topic的功能包:

cd ~/mrobot_ws/

catkin_create_pkg learning_topic roscpp rospy std_msgs geometry_msgs turtlesim

      其中catkin_create_pkg命令的作用是创建一个新的catkin功能包,上面代码的作用是创建一个名为learning_topic的功能包,并添加该功能包所需要的依赖roscpp、rospy、std_msgs、geometry、turtle司马。

2.在learning_topic文件下的src文件夹中创建velocity_publisher.cpp文件,构建代码框架:

#include

#include

int main(int argc,char **argv){

return 0;

}

3.在main函数中初始化ROS节点,在ROS系统中注册节点名称:

ros::init(argc,argv,“velocity_publisher” );

ros::init(NodeHandle nh;

4.接着创建句柄,实例化Node,并创建发布者对象: 

ros::init(Publisher turtle_vel_pub=nh.advertise(“turtle1/cmd_vel”,10);

    NodeHandle是与ROS系统通信的主要接入点,调用NodeHandle的advertise函数将发布一个话题Topic,函数的第一个参数为Topic名称,第二个参数为消息队列大小。在实际应用中,消息的发送和接收之间不是同步进行的,存在消息发布和接受的时间差。因此ROS会把发布的消息写入缓冲区,供接收程序读取,一旦超过缓冲区信息数量,最早的数据就会被丢弃。注明了消息队列的消息类型。

    以上代码在执行时告诉主机,将在一个名字为“/turtle1/cmd_vel”的Topic上发布一个geometry_msgs:: Twist类型的消息,这就使得主机告诉所有订阅了“/turtle1/cmd_vel” Topic的节点,我们将在这个Topic上发布的数据;第二个参数告诉主机,能缓冲10条信息,超过了十条就会覆盖之前的信息。

5.设定发布频率,单位为赫兹(Hz),本例设置为10Hz,即每秒发布10次数据:

ros::Rate loop_rate(10);

6.循环发布线速度为0.5m/s、角速度为0.2rad/s的消息并打印,至此velocity_publisher.cpp代码部分完成:

while(ros::ok()){

geometry_msgs::Twist vel_msg;//ROS预定义消息类型

vel_msg.linear.x=0.5;

vel_msgs.angular.z=0.2;

turtle_vel_pub.publish(vel_msg);

ROS_INFO(“Publish turtle velocity command[%0.2f m/s,%0.2f rad/s]”,vel_msg.linera.x,velmsg.angular.z);

loop_rate.sleep();

}

7.配置CMakeLists.txt中的编译规则,将下面的代码插入到CMakeLists.txt文件中:

add_executable(velocity_publisher src/velcity_publisher.cpp)

target_link_libraries(velocity_publisher ${catkin_LIBRARIES})

8.编译并运行:

cd ~/catkin_ws

catkin_make

source devel/setup.bash

#新建终端,先开启master

roscore

#新建终端,启动小海龟

rosrun turtlesim turtlesim_node

#回到刚编译成功的第一个终端,运行我们自己编写的发布者程序

rosrun learning_topic velocity_publisher

#另外启动一个终端,输入下面的命令,可以看到当前的Topic列表

rostopic list

   启动程序后,小海龟会按照设定好的线速度和角速度移动。由于线速度和角速度都是固定的,所以小海龟的移动轨迹是一个圆,效果如下图所示:

ROS编程基础_第3张图片

 

图4 小海龟运动图

1.4.2.Topic话题中的Subscriber

通过订阅小海龟的位姿信息来介绍Topic话题中的Subscriber。

1.在learning_topic文件夹中创建pose_subscriber.cpp文件,并构建代码框架:

#include

#include”tyrtlesim/Pose.h”

int main(char argc,char **argv){

return 0;

}

2.在main函数上方编写poseCallback回调函数,打印订阅内容:

void poseCallback(const turtlesim::Pose::ConstPtr& msg){

ROS_INFO(“Turtle pose:x:%0.6f,y:%0.6f”,msg->,msg->y);

}

3.在main函数中初始化ROS节点,在ROS系统中注册节点名称:

ros init(argc,argv,”pose_subscriber”);//初始化ROS节点

4.创建句柄,实例化Node,并创建订阅者对象:

ros::NodeHandle n;

ros::Subscriber pose_sub=n.subscribe(“/turtle1/pose”,10,poseCallback);

上面的代码告诉ROS节点管理器,我们将会从”/turtle1/pose“这个话题中订阅消息,当有消息到达时会自动调用这里指定的poseCallback回调函数。这里的参数10表示订阅队列的大小,如果消息处理的不够快,之前的消息则会被舍弃。

5.循环等待回调函数:

ros::spin();

6.配置CMakeLists.txt中的编译规则,将下面代码插入CMakeLists.txt文件当中:

add_executable(pose_subscriber src/pose_subscriber.cpp)

target_link_libraries(pose_subscriber ${catkin_LIBRARIES})

7.编译并运行:

cd ~/catkin_ws                        #自己创建的工作区间

catkin_make

source devel/setup.bash

roscore     #打开master

rosrun turtlesim turtlesim_node       #新开终端

source devel/setup.bash

rosrun learning_topic pose_subscriber  #新开终端

【注意】由于ROS应用了C++11标准,需要将CMakeLists.txt文件中的add_complie_options(-std=c++11)注释解开或者添加以上代码。

你可能感兴趣的:(机器人)