ROS基础(一)

ROS基础

参考 :https://sychaichangkun.gitbooks.io/ros-tutorial-icourse163/content/

ch1 ROS简介与安装

安装ROS-Academy-for-Beginners教学包

https://sychaichangkun.gitbooks.io/ros-tutorial-icourse163/content/chapter1/1.5.html

rosrun robot_sim_demo robot_keyboard_teleop.py

出错

yhs@yhs-CN15S:~/tutorial_ws$ rosrun robot_sim_demo robot_keyboard_teleop.py
[rospack] Error: package 'robot_sim_demo' not found

解决:

source ~/tutorial_ws/devel/setup.bash
#或者
rospack profile

新开的窗口没有进行source 导致找不到robot_sim_demo这个包,以及脚本文件。

安装roboware

参考 https://blog.csdn.net/JIEJINQUANIL/article/details/102572722

ch2 ROS文件系统

2.1 Catkin编译系统

ROS采用的是CMake,并且ROS对CMake进行了扩展,于是便有了Catkin编译系统。在这里插入图片描述
目前的ROS同时支持着rosbuild和Catkin两种编译系统,但ROS的核心软件包也已经全部转换为Catkin。rosbuild已经被逐步淘汰,所以建议初学者直接上手Catkin。

2.1.1Catkin特点

Catkin是基于CMake的编译构建系统,具有以下特点:

  • Catkin沿用了包管理的传统像 find_package()基础结构,pkg-config
  • 扩展了CMake,例如
    • 软件包编译后无需安装(头文件和库文件)就可使用
    • 自动生成find_package()代码,pkg-config文件
    • 解决了多个软件包构建顺序问题
      一个Catkin的软件包(package)必须要包括两个文件:
  • package.xml:包括了package的描述信息
    • name, description, version, maintainer(s), license
    • opt. authors, url’s, dependencies, plugins, etc…
  • CMakeLists.txt: 构建package所需的CMake文件
    • 调用Catkin的函数/宏
    • 解析package.xml
    • 找到其他依赖的catkin软件包
    • 将本软件包添加到环境变量
2.1.2Catkin工作原理

catkin编译的工作流程如下:

  1. 首先在工作空间catkin_ws/src/下递归的查找其中每一个ROS的package。
  2. package中会有package.xml和CMakeLists.txt文件,Catkin(CMake)编译系统依据CMakeLists.txt文件,从而生成makefiles(放在catkin_ws/build/)。
    然后make刚刚生成的makefiles等文件,编译链接生成可执行文件(放在catkin_ws/devel)。
    也就是说,Catkin就是将cmake与make指令做了一个封装从而完成整个编译过程的工具。catkin有比较突出的优点,主要是:
  • 操作更加简单
  • 一次配置,多次使用
  • 跨依赖项目编译
2.1.3使用catkin_make进行编译
#进入工作空间后,catkin_make编译
mkdir -p ~/catkin_ws/src  
cd ~/tutorial_ws
catkin_make

之后,得到build和devel
在这里插入图片描述

  • src/: ROS的catkin软件包(源代码包)
  • build/: catkin(CMake)的缓存信息和中间文件
  • devel/: 生成的目标文件(包括头文件,动态链接库,静态链接库,可执行文件等)、环境变量
    src/中的编译单元是package,在编译时,catkin编译系统会递归的查找和编译src/下的每一个源代码包。因此你也可以把几个源代码包放到同一个文件夹下,如下图所示:在这里插入图片描述
2.2.1 package

ROS中的package的不仅是Linux上的软件包,更是catkin编译的基本单元,我们调用catkin_make编译的对象就是一个个ROS的package,也就是说任何ROS程序只有组织成package才能编译。所以package也是ROS源代码存放的地方,任何ROS的代码无论是C++还是Python都要放到package中,这样才能正常的编译和运行。
一个package可以编译出来多个目标文件(ROS可执行程序、动态静态库、头文件等等)

  ├── CMakeLists.txt    #package的编译规则(必须)
  ├── package.xml       #package的描述信息(必须)
  ├── src/              #源代码文件
  ├── include/          #C++头文件
  ├── scripts/          #可执行脚本
  ├── msg/              #自定义消息
  ├── srv/              #自定义服务
  ├── models/           #3D模型文件
  ├── urdf/             #urdf文件
  ├── launch/           #launch文件

其中定义package的是CMakeLists.txt和package.xml,这两个文件是package中必不可少的。catkin编译系统在编译前,首先就要解析这两个文件。这两个文件就定义了一个package,是必须的。

  • CMakeLists.txt: 定义package的包名、依赖、源文件、目标文件等编译规则,是package不可少的成分
  • package.xml: 描述package的包名、版本号、作者、依赖等信息,是package不可少的成分
  • src/: 存放ROS的源代码,包括C++的源码和(.cpp)以及Python的module(.py)
  • include/: 存放C++源码对应的头文件
  • scripts/: 存放可执行脚本,例如shell脚本(.sh)、Python脚本(.py)
  • msg/: 存放自定义格式的消息(.msg)
  • srv/: 存放自定义格式的服务(.srv)
  • models/: 存放机器人或仿真场景的3D模型(.sda, .stl, .dae等)
  • urdf/: 存放机器人的模型描述(.urdf或.xacro)
  • launch/: 存放launch文件(.launch或.xml)
2.2.2 创建package

创建一个package需要在catkin_ws/src下,用到catkin_create_pkg命令,用法是:
catkin_create_pkg package depends
其中package是包名,depends是依赖的包名,可以依赖多个软件包。

例如,新建一个package叫做test_pkg,依赖roscpp、rospy、std_msgs(常用依赖)。

$ catkin_create_pkg test_pkg roscpp rospy std_msgs
2.3.1 Metapackage

在教学包内,有一个ros-academy-for-beginners软件包,该包即为一个metapacakge,其中有且仅有两个文件:CMakeLists.txt和pacakge.xml。
metapacakge中的以上两个文件和普通pacakge不同点是:

  • CMakeLists.txt:加入了catkin_metapackage()宏,指定本软件包为一个metapacakge。
  • package.xml:标签将所有软件包列为依赖项,标签中添加标签声明。
    metapacakge在我们实际开发一个大工程时可能有用

2.3 其他常见文件类型

在ROS的pacakge中,还有其他许多常见的文件类型,这里做个总结。

2.3.1 launch文件

launch文件一般以.launch或.xml结尾,它对ROS需要运行程序进行了打包,通过一句命令来启动。一般launch文件中会指定要启动哪些package下的哪些可执行程序,指定以什么参数启动,以及一些管理控制的命令。 launch文件通常放在软件包的launch/路径中中。

2.3.2 msg/srv/action文件

ROS程序中有可能有一些自定义的消息/服务/动作文件,为程序的发者所设计的数据结构,这类的文件以.msg,.srv,.action结尾,通常放在package的msg/,srv/,action/路径下。

2.3.3 urdf/xacro文件

urdf/xacro文件是机器人模型的描述文件,以.urdf或.xacro结尾。它定义了机器人的连杆和关节的信息,以及它们之间的位置、角度等信息,通过urdf文件可以将机器人的物理连接信息表示出来。并在可视化调试和仿真中显示。

2.3.4 yaml文件

yaml文件一般存储了ROS需要加载的参数信息,一些属性的配置。通常在launch文件或程序中读取.yaml文件,把参数加载到参数服务器上。通常我们会把yaml文件存放在param/路径下

2.3.5 dae/stl文件

dae或stl文件是3D模型文件,机器人的urdf或仿真环境通常会引用这类文件,它们描述了机器人的三维模型。相比urdf文件简单定义的性状,dae/stl文件可以定义复杂的模型,可以直接从solidworks或其他建模软件导出机器人装配模型,从而显示出更加精确的外形。

2.3.6 rviz文件

rviz文件本质上是固定格式的文本文件,其中存储了RViz窗口的配置(显示哪些控件、视角、参数)。通常rviz文件不需要我们去手动修改,而是直接在RViz工具里保存,下次运行时直接读取。

Ch3 ROS通信

ROS的通信架构是ROS的灵魂。ROS通信架构包括各种数据的处理,进程的运行,消息的传递等等。
其中首先介绍了最小的进程单元节点Node,和节点管理器Node master。了解了ROS中的进程都是由很多的Node组成,并且由Node master来管理这些节点。

ROS的“发动机”——launch文件,学习它的格式和内容,更深入的理解ROS在启动运行时它的工作都是由什么进程支配的,从而理解启动运行的原理。

在后面的几节我们介绍了ROS中通信方式。ROS中的通信方式有四种,主题、服务、参数服务器、动作库。每个通信方式都有自己的特点,本章首先介绍话题通信方式–topic。

3.1 Node&Master

ROS的世界里,最小的进程单元就是节点(node)。一个软件包里可以有多个可执行文件,可执行文件在运行之后就成了一个进程(process),这个进程在ROS中就叫做节点。 从程序角度来说,node就是一个可执行文件(通常为C++编译生成的可执行文件、Python脚本)被执行,加载到了内存之中;从功能角度来说,通常一个node负责者机器人的某一个单独的功能。由于机器人的功能模块非常复杂,我们往往不会把所有功能都集中到一个node上,而会采用分布式的方式,把鸡蛋放到不同的篮子里。例如有一个node来控制底盘轮子的运动,有一个node驱动摄像头获取图像,有一个node驱动激光雷达,有一个node根据传感器信息进行路径规划……这样做可以降低程序发生崩溃的可能性,试想一下如果把所有功能都写到一个程序中,模块间的通信、异常处理将会很麻烦。

我们在1.4节打开了小海龟的运动程序和键盘控制程序,在1.5节同样启动了键盘运动程序,这每一个程序便是一个node。ROS系统中不同功能模块之间的通信,也就是节点间的通信。我们可以把键盘控制替换为其他控制方式,而小海龟运动程序、机器人仿真程序则不用变化。这样就是一种模块化分工的思想。

3.1.1 Master

master在整个网络通信架构里相当于管理中心,管理着各个node。node首先在master处进行注册,之后master会将该node纳入整个ROS程序中。node之间的通信也是先由master进行“牵线”,才能两两的进行点对点通信。当ROS程序启动时,第一步首先启动master,由节点管理器处理依次启动node。

3.1.2 启动Master和Node

启动ros

$ roscore

此时ROS master启动,同时启动的还有rosout和parameter server,其中rosout是负责日志输出的一个节点,其作用是告知用户当前系统的状态,包括输出系统的error、warning等等,并且将log记录于日志文件中,parameter server即是参数服务器,它并不是一个node,而是存储参数配置的一个服务器,后文我们会单独介绍。每一次我们运行ROS的节点前,都需要把master启动起来,这样才能够让节点启动和注册。

master之后,节点管理器就开始按照系统的安排协调进行启动具体的节点。节点就是一个进程,只不过在ROS中它被赋予了专用的名字里——node。在第二章我们介绍了ROS的文件系统,我们知道一个package中存放着可执行文件,可执行文件是静态的,当系统执行这些可执行文件,将这些文件加载到内存中,它就成为了动态的node。具体启动node的语句是:

rosrun pkg_name node_name

通常我们运行ROS,就是按照这样的顺序启动,有时候节点太多,我们会选择用launch文件来启动.
Master、Node之间以及Node之间的关系如下图所示

3.1.3 rosrun 和rosnode 命令

rosnode help来查看rosnode命令的用法

3.2 launch文件

ROS为我们提供了一个命令能一次性启动master和多个node。该命令是:

$ roslaunch pkg_name file_name.launch

roslaunch命令首先会自动进行检测系统的roscore有没有运行,也即是确认节点管理器是否在运行状态中,如果master没有启动,那么roslaunch就会首先启动master,然后再按照launch的规则执行。launch文件里已经配置好了启动的规则。 所以roslaunch就像是一个启动工具,能够一次性把多个节点按照我们预先的配置启动起来,减少我们在终端中一条条输入指令的麻烦。

3.3 ROS的通信

  • Topic 主题
  • Service 服务
  • Parameter Service 参数服务器
  • Actionlib 动作库
3.3.1 Topic

对于实时性、周期性的消息,使用topic来传输是最佳的选择**。topic是一种点对点的单向通信方式,这里的“点”指的是node**,也就是说node之间可以通过topic方式来传递信息。topic要经历下面几步的初始化过程:首先,publisher节点和subscriber节点都要到节点管理器进行注册,然后publisher会发布topic,subscriber在master的指挥下会订阅该topic,从而建立起sub-pub之间的通信。注意整个过程是单向的。其结构示意图如下:
在这里插入图片描述

3.3.2 Topic通信示例

以摄像头画面的发布、处理、显示为例讲讲topic通信的流程。在机器人上的摄像头拍摄程序是一个node(圆圈表示,我们记作node1),当node1运行启动之后,它作为一个Publisher就开始发布topic。比如它发布了一个topic(方框表示),叫做/camera_rgb,是rgb颜色信息,即采集到的彩色图像。同时,node2假如是图像处理程序,它订阅了/camera_rgb这个topic,经过节点管理器的介绍,它就能建立和摄像头节点(node1)的连接。

那么怎么样来理解“异步”这个概念呢?在node1每发布一次消息之后,就会继续执行下一个动作,至于消息是什么状态、被怎样处理,它不需要了解;而对于node2图像处理程序,它只管接收和处理/camera_rgb上的消息,至于是谁发来的,它不会关心。所以node1、node2两者都是各司其责,不存在协同工作,我们称这样的通信方式是异步的。在这里插入图片描述
ROS是一种分布式的架构,一个topic可以被多个节点同时发布,也可以同时被多个节点接收。比如在这个场景中用户可以再加入一个图像显示的节点,我们在想看看摄像头节点的画面,则可以用自己的笔记本连接到机器人上的节点管理器,然后在自己的电脑上启动图像显示节点。
这就体现了分布式系统通信的好处:扩展性好、软件复用率高。
总结三点:

  1. topic通信方式是异步的,发送时调用publish()方法,发送完成立即返回,不用等待反馈。
  2. subscriber通过回调函数的方式来处理消息。
  3. topic可以同时有多个subscribers,也可以同时有多个publishers。ROS中这样的例子有:/rosout、/tf等等。
3.3.3 rostopic 命令
3.3.4 测试实例

首先打开ROS-Academy-for-Beginners的模拟场景,输入roslaunch robot_sim_demo robot_spawn.launch,看到我们仿真的模拟环境。该launch文件启动了模拟场景、机器人。

  1. 查看当前模拟器中存在的topic,输入命令rostopic list。可以看到许多topic,它们可以视为模拟器与外界交互的接口。
  2. 查询topic/camera/rgb/image_raw的相关信息:rostopic info /camera/rgb/image_raw。则会显示类型信息type,发布者和订阅者的信息。
  3. 上步我们在演示中可以得知,并没有订阅者订阅该主题,我们指定image_view来接收这个消息,运行命令rosrun image_view image_view image:=<image topic> [transport]。我们可以看到message,即是上一步中的type。
  4. 同理我们可以查询摄像头的深度信息depth图像。
  5. 在用键盘控制仿真机器人运动的时候,我们可以查看速度指令topic的内容rostopic echo /cmd_vel ,可以看到窗口显示的各种坐标参数在不断的变化。
    通过这些实例的测试,帮助我们更快的掌握topic各种操作命令的使用,以及对topic通信的理解。

3.4 Msg

topic有很严格的格式要求,比如上节的摄像头进程中的rgb图像topic,它就必然要遵循ROS中定义好的rgb图像格式。这种数据格式就是Message。Message按照定义解释就是topic内容的数据类型,也称之为topic的格式标准。这里和我们平常用到的Massage直观概念有所不同,这里的Message不单单指一条发布或者订阅的消息,也指定为topic的格式标准。

3.5 service

topic是ROS中的一种单向的异步通信方式。当一些节点只是临时而非周期性的需要某些数据,就需要有另外一种请求-查询式的通信模型。这节我们来介绍ROS通信中的另一种通信方式——service(服务)。

service方式在通信模型上与topic做了区别。Service通信是双向的,它不仅可以发送消息,同时还会有反馈。所以service包括两部分,一部分是请求方(Clinet),另一部分是应答方/服务提供方(Server)。这时请求方(Client)就会发送一个request,要等待server处理,反馈回一个reply,这样通过类似“请求-应答”的机制完成整个服务通信。

这种通信方式的示意图如下:
Node B是server(应答方),提供了一个服务的接口,叫做/Service,我们一般都会用string类型来指定service的名称,类似于topic。Node A向Node B发起了请求,经过处理后得到了反馈。
在这里插入图片描述
Service是同步通信方式,所谓同步就是说,此时Node A发布请求后会在原地等待reply,直到Node B处理完了请求并且完成了reply,Node A才会继续执行。Node A等待过程中,是处于阻塞状态的通信。这样的通信模型没有频繁的消息传递,没有冲突与高系统资源的占用,只有接受请求才执行服务,简单而且高效。

名称TopicService
通信方式异步通信同步通信
实现原理TCP/IPTCP/IP
通信模型Publish-SubscribeRequest-Reply
映射关系Publish-Subscribe(多对多)Request-Reply(多对一)
特点接受者收到数据会回调(Callback)远程过程调用(RPC)服务器端的服务
应用场景连续、高频的数据发布偶尔使用的功能/具体的任务
举例激光雷达、里程计发布数据开关传感器、拍照、逆解计算

注意:远程过程调用(Remote Procedure Call,RPC),可以简单通俗的理解为在一个进程里调用另一个进程的函数。

3.6 Srv

类似msg文件,srv文件是用来描述服务(service数据类型的,service通信的数据格式定义在*.srv中。它声明了一个服务,包括请求(request)和响应(reply)两部分。其格式声明如下:

举例:

msgs_demo/srv/DetectHuman.srv

bool start_detect
---
my_pkg/HumanPose[] pose_data
msgs_demo/msg/HumanPose.msg

std_msgs/Header header

string uuid
int32 number_of_joints
my_pkg/JointPose[]joint_data
msgs_demo/msg/JointPose.msg

string joint_name

geometry_msgs/Pose pose
floar32 confidence

以DetectHUman.srv文件为例,该服务例子取自OpenNI的人体检测ROS软件包。它是用来查询当前深度摄像头中的人体姿态和关节数的。srv文件格式很固定,第一行是请求的格式,中间用—隔开,第三行是应答的格式。在本例中,请求为是否开始检测,应答为一个数组,数组的每个元素为某个人的姿态(HumanPose)。而对于人的姿态(HumanPose),其实是一个msg,所以srv可以嵌套msg在其中,但它不能嵌套srv。

定义完了msg、srv文件,还有重要的一个步骤就是修改package.xml和修改CMakeList.txt。这些文件需要添加一些必要的依赖等,例如:

<build_depend>** message_generation **</build_depend>
<run_depend>** message_runtime **</run_depend>

上述文本中“**”所引就是新添加的依赖。又例如:

find_package(...roscpp rospy std_msgs ** message_generation **)
catkin_package(
...
CATJIN_DEPENDS ** message_runtime ** ...
...)

add_message_file(
FILES
** DetectHuman.srv **
** HumanPose.msg **
** JointPos.msg **)

** generate_messages(DEPENDENCIES std_msgs) **

添加的这些内容指定了srv或者msg在编译或者运行中需要的依赖。具体的作用我们初学者可不深究,我们需要了解的是,无论我们自定义了srv,还是msg,修改上述部分添加依赖都是必不可少的一步。

3.7 Parameter server 参数服务器

前文介绍了ROS中常见的两种通信方式——主题和服务,这节介绍另外一种通信方式——参数服务器(parameter server)。与前两种通信方式不同,参数服务器也可以说是特殊的“通信方式”。特殊点在于参数服务器是节点存储参数的地方、用于配置参数,全局共享参数参数服务器使用互联网传输,在节点管理器中运行,实现整个通信过程。

参数服务器,作为ROS中另外一种数据传输方式,有别于topic和service,它更加的静态。参数服务器维护着一个数据字典,字典里存储着各种参数和配置

字典简介
何为字典,其实就是一个个的键值对,每一个key都是唯一的,且每一个key对应着一个value。也可以说字典就是一种映射关系,在实际的项目应用中,因为字典的这种静态的映射特点,我们往往将一些不常用到的参数和配置放入参数服务器里的字典里,这样对这些数据进行读写都将方便高效。

维护方式
参数服务器的维护方式非常的简单灵活,总的来讲有三种方式:

  • 命令行维护
  • launch文件内读写
  • node源码
    下面我们来一一介绍这三种维护方式。
3.7.1 命令行维护

使用命令行来维护参数服务器,主要使用rosparam语句来进行操作的各种命令,如下表:

rosparam 命令作用
rosparam set param_key param_value设置参数
rosparam get param_key显示参数
rosparam load file_name从文件加载参数
rosparam dump file_name保存参数到文件
rosparam delete删除参数
rosparam list列出参数名称

load&&dump文件
load和dump文件需要遵守YAML格式,YAML格式具体示例如下:

name:‘Zhangsan’
age:20
gender:‘M’
score{Chinese:80,Math:90}
score_history:[85,82,88,90]
简明解释。就是“名称+:+值”这样一种常用的解释方式。一般格式如下:
key : value
遵循格式进行定义参数。其实就可以把YAML文件的内容理解为字典,因为它也是键值对的形式。

3.7.2 launch文件读写

launch文件中有很多标签,而与参数服务器相关的标签只有两个,一个是<param>,另一个是<rosparam>。这两个标签功能比较相近,但<param>一般只设置一个参数,请看下例:
(1) (2) (3)
观察上例比如序号3的param就定义了一个key和一个value,交给了参数服务器维护。而序号1的param只给出了key,没有直接给出value,这里的value是由 后面的脚本运行结果作为value进行定义的。序号(2)就是rosparam的典型用法,先指定一个YAML文件,然后施加command,其效果等于rosparam load file_name 。

3.7.3 node源码

除了上述最常用的两种读写参数服务器的方法,还有一种就是修改ROS的源码,也就是利用API来对参数服务器进行操作。具体内容我们学习完后面章节再进行介绍。

3.8 Action

Actionlib是ROS中一个很重要的库,类似service通信机制,actionlib也是一种请求响应机制的通信方式,actionlib主要弥补了service通信的一个不足,就是当机器人执行一个长时间的任务时,假如利用service通信方式,那么publisher会很长时间接受不到反馈的reply,致使通信受阻。当service通信不能很好的完成任务时候,actionlib则可以比较适合实现长时间的通信过程,actionlib通信过程可以随时被查看过程进度,也可以终止请求,这样的一个特性,使得它在一些特别的机制中拥有很高的效率。

4.4.2 通信原理
Action的工作原理是client-server模式,也是一个双向的通信模式。通信双方在ROS Action Protocol下通过消息进行数据的交流通信。client和server为用户提供一个简单的API来请求目标(在客户端)或通过函数调用和回调来执行目标(在服务器端)。

工作模式的结构示意图如下:
在这里插入图片描述

通信双方在ROS Action Protocal下进行交流通信是通过接口来实现,如下图:
在这里插入图片描述

我们可以看到,客户端会向服务器发送目标指令和取消动作指令,而服务器则可以给客户端发送实时的状态信息,结果信息,反馈信息等等,从而完成了service没法做到的部分.

4.4.3 Action 规范
利用动作库进行请求响应,动作的内容格式应包含三个部分,目标、反馈、结果。

目标
机器人执行一个动作,应该有明确的移动目标信息,包括一些参数的设定,方向、角度、速度等等。从而使机器人完成动作任务。

反馈
在动作进行的过程中,应该有实时的状态信息反馈给服务器的实施者,告诉实施者动作完成的状态,可以使实施者作出准确的判断去修正命令。

结果
当运动完成时,动作服务器把本次运动的结果数据发送给客户端,使客户端得到本次动作的全部信息,例如可能包含机器人的运动时长,最终姿势等等。

4.4.4 Action规范文件格式
Action规范文件的后缀名是.action,它的内容格式如下:

# Define the goal
uint32 dishwasher_id  # Specify which dishwasher we want to use
---
# Define the result
uint32 total_dishes_cleaned
---
# Define a feedback message
float32 percent_complete

4.4.5 Action实例详解
Actionlib是一个用来实现action的一个功能包集。我们在demo中设置一个场景,执行一个搬运的action,搬运过程中客户端会不断的发回反馈信息,最终完成整个搬运过程.

本小节的演示源码在课程的演示代码包里,此处为链接.

首先写handling.action文件,类比如上的格式.包括三个部分,目标,结果,反馈.如下:

# Define the goal
uint32 handling_id 
---
# Define the result
uint32 Handling_completed
---
# Define a feedback message
float32 percent_complete

写完之后修改文件夹里CmakeLists.txt如下内容:

find_package(catkin REQUIRED genmsg actionlib_msgs actionlib)

add_action_files(DIRECTORY action FILES DoDishes.action) 

generate_messages(DEPENDENCIES actionlib_msgs)

add_action_files(DIRECTORY action FILES Handling.action)

generate_messages( DEPENDENCIES actionlib_msgs)

修改package.xml,添加所需要的依赖如下:

<build_depend>actionlib </build_depend>
<build_depend>actionlib_msgs</build_depend>
<run_depend>actionlib</run_depend>
<run_depend>actionlib_msgs</run_depend>

然后回到工作空间 catkin_ws进行编译.

本例中设置的的action,定义了一个搬运的例子**,首先写客户端**,实现功能发送action请求,包括进行目标活动,或者目标活动.**之后写服务器,**实验返回客户端活动当前状态信息,结果信息,和反馈信息.从而实现action.本例测试结果截图如下:
在这里插入图片描述

小结
至此,ROS通信架构的四种通信方式就介绍结束,我们可以对比学习这四种通信方式,去思考每一种通信的优缺点和适用条件,在正确的地方用正确的通信方式,这样整个ROS的通信会更加高效,机器人也将更加的灵活和智能。机器人学会了通信,也就相当于有了“灵魂”。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值