热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ROS2入门教程|动作(Action)通信与自定义接口

本系列教程作者:小鱼公众号:鱼香ROSQQ交流群:139707339教学视频地址:小鱼的B站完整文档地址:鱼香

本系列教程作者:小鱼
公众号:鱼香ROS
QQ交流群:139707339
教学视频地址:小鱼的B站
完整文档地址:鱼香ROS官网
版权声明:如非允许禁止转载与商业用途。

你好,我是小鱼。通过前面章节的学习,你已经掌握了ROS2中四大通信利器中话题、服务、参数这三个,还差最后一个就能将ROS2的通信机制全部打包带回家了,这节课小鱼就带你一起认识一下Action,并带你动手体验一下Action通信。

1.Action背景

前面章节学习了话题、服务、参数。

话题适用于节点间单向的频繁的数据传输,服务则适用于节点间双向的数据传递,而参数则用于动态调整节点的设置,动作Action和他们三个有什么不同之处呢?

如果这些问题体现在机器人上,可能是这样子的。我们通过服务服务发送一个目标点给机器人,让机器人移动到该点:

  • 你不知道机器人有没有处理移动到目标点的请求(不能确认服务端接收并处理目标)
  • 假设机器人收到了请求,你不知道机器人此时的位置和距离目标点的距离(没有反馈)
  • 假设机器人移动一半,你想让机器人停下来,也没有办法通知机器人

上面的场景在机器人控制当中经常出现,比如控制导航程序,控制机械臂运动,控制小乌龟旋转等,很显然单个话题和服务不能满足我们的使用,因此ROS2针对控制这一场景,基于原有的话题和服务,设计了动作(Action)这一通信方式来解决这一问题。

2.Action的组成部分

知道了Action的出现原因,接着说说Action的三大组成部分目标、反馈和结果。

  • 目标:即Action客户端告诉服务端要做什么,服务端针对该目标要有响应。解决了不能确认服务端接收并处理目标问题
  • 反馈:即Action服务端告诉客户端此时做的进度如何(类似于工作汇报)。解决执行过程中没有反馈问题
  • 结果:即Action服务端最终告诉客户端其执行结果,结果最后返回,用于表示任务最终执行情况。

参数是由服务构建出来了,而Action是由话题和服务共同构建出来的(一个Action = 三个服务+两个话题) 三个服务分别是:1.目标传递服务 2.结果传递服务 3.取消执行服务 两个话题:1.反馈话题(服务发布,客户端订阅) 2.状态话题(服务端发布,客户端订阅)

图片

3.感受Action

带着前面对Action的了解,接着我们一起来直观的通过小乌龟的案例来感受一下Action的魅力。

3.1 启动乌龟模拟器和键盘控制节点

乌龟模拟器

ros2 run turtlesim turtlesim_node

键盘控制节点

ros2 run turtlesim turtle_teleop_key

打开键盘控制节点后,你应该窗口中可以看到下面的提示

Use arrow keys to move the turtle.
Use G|B|V|C|D|E|R|T keys to rotate to absolute orientations. 'F' to cancel a rotation.

有请翻译官小鱼(其实用Deppl翻译的)

使用方向键移动乌龟。
用G、B、V、C、D、E、R、T键旋转到绝对方向。'F'可以取消旋转。

这段提示什么意思呢?其实就是字面的意思,

小乌龟键盘控制节点,提供两种可选的控制方式。

  • 方向键,通过话题(Topic)控制小乌龟的(直接发送移动话题)
  • 绝对旋转,则是采用动作(Action)来控制的小乌龟

3.2 使用绝对旋转(Action)控制小乌龟

使用绝对旋转控制小乌龟即使用Action来控制小乌龟。

在小乌龟的遥控窗口我们使用键盘上的F按键周围的按键来尝试运行控制下小乌龟的方向,你会看到小乌龟根据我们所按下按键所在的方向来在原地进行旋转。

同时在旋转的过程中,我们可以使用F按键,来取消小乌龟的运动。

4. Action的CLI工具

Action的命令行工具一共有三个,下面我们一一介绍。

4.1 action list

该命令用于获取目前系统中的action列表。

ros2 action list

你将看到

/turtle1/rotate_absolute

如果在list后加入-t参数,即可看到action的类型

/turtle1/rotate_absolute [turtlesim/action/RotateAbsolute]

知道了接口类型之后,可以使用接口相关CLI指令获取接口的信息

ros2 interface show turtlesim/action/RotateAbsolute

结果

# The desired heading in radians
float32 theta
---
# The angular displacement in radians to the starting position
float32 delta
---
# The remaining rotation in radians
float32 remaining

4.2 action info

查看action信息,在终端中输入下面的指令。

ros2 action info /turtle1/rotate_absolute

你将看到,action客户端和服务段的数量以及名字。

Action: /turtle1/rotate_absolute
Action clients: 1/teleop_turtle
Action servers: 1/turtlesim

4.3 action send_goal

该指令用于发送actin请求到服务端,我们可以模拟下,让小乌龟转到我们定义的角度。

我们只需要把goal发给服务端即可,根据goal的定义,我们可以看到goal是由一个浮点类型的theta组成的,我们把theta发给服务端。

发送弧度制1.6给小乌龟

ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: 1.6}"

结果

Waiting for an action server to become available...
Sending goal:theta: 1.6Goal accepted with ID: b215ad060899444793229171e76481c7Result:delta: -1.5840003490447998Goal finished with status: SUCCEEDED

我们可以看到goal和result,但是没有看到feedback,这里我们需要加一个参数 --feedback

加上这个参数我们再发送一次。

ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: 1.5}" --feedback

可以看到了,这次的日志中多出了很多实时的反馈,反馈的数值是小乌龟当前的角度与我们给定的目标角度之间的差值,可以看到一直在变小。

Waiting for an action server to become available...
Sending goal:theta: 1.5Feedback:remaining: -0.0840003490447998Goal accepted with ID: b368de0ed1a54e00890f1b078f4671c8Feedback:remaining: -0.06800031661987305Feedback:remaining: -0.05200028419494629Feedback:remaining: -0.03600025177001953Feedback:remaining: -0.020000219345092773Feedback:remaining: -0.004000186920166016Result:delta: 0.08000016212463379Goal finished with status: SUCCEEDED

5.自定义通信接口

我们接下来以控制机器人移动到点为例子,来学习Action通信。因为这个场景是我们自己定义的,ROS2并没有拿来就用的接口,所以我们需要自定义Action通信接口。

5.1 创建接口功能包

创建功能包

cd chapt4_ws/
ros2 pkg create robot_control_interfaces --build-type ament_cmake --destination-directory src --maintainer-name "fishros" --maintainer-email "fishros@foxmail.com"

创建接口文件

mkdir -p src/robot_control_interfaces/actiontouch src/robot_control_interfaces/action/MoveRobot.action

packages.xml

rosidl_default_generatorsrosidl_interface_packages

CMakeLists.txt

find_package(ament_cmake REQUIRED)
find_package(rosidl_default_generators REQUIRED)rosidl_generate_interfaces(${PROJECT_NAME}"action/MoveRobot.action"
)

5.2 编写接口

# Goal: 要移动的距离
float32 distance
---
# Result: 最终的位置
float32 pose
---
# Feedback: 中间反馈的位置和状态
float32 pose
uint32 status
uint32 STATUS_MOVEING = 3
uint32 STATUS_STOP = 4

5.3 编译生成接口

colcon build --packages-select robot_control_interfaces

编译成功后,即可看到C++头文件和Python相关文件

  • C++ Action消息头文件目录install/robot_control_interfaces/include
  • Python Action消息文件目录install/robot_control_interfaces/local/lib/python3.10

6.总结

本节我们学习了Action并手动创建了Action的接口,下一节小鱼将带你一起使用接口完成任务。


推荐阅读
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讲述了如何通过代码在Android中更改Recycler视图项的背景颜色。通过在onBindViewHolder方法中设置条件判断,可以实现根据条件改变背景颜色的效果。同时,还介绍了如何修改底部边框颜色以及提供了RecyclerView Fragment layout.xml和项目布局文件的示例代码。 ... [详细]
  • 本文介绍了C++中省略号类型和参数个数不确定函数参数的使用方法,并提供了一个范例。通过宏定义的方式,可以方便地处理不定参数的情况。文章中给出了具体的代码实现,并对代码进行了解释和说明。这对于需要处理不定参数的情况的程序员来说,是一个很有用的参考资料。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
author-avatar
woainimamamamama
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有