ROS:动作(action)通信

概览

ROS引入通信机制,是为了实现ROS节点(进程)之间的通信。利用ROS进程的分布式框架,可以使得每个进程独立的工作,甚至分布于不同的主机工作。机器人上的各种传感器,比如雷达、GPS等,需要传递数据以实现对机器人的合理控制,进程通信的实现是传输数据的关键。

其基本通信方式分为三种:

动作(action)通信

为什么需要

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

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

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

很显然单个话题和服务不能满足我们的使用,因此ROS2针对控制这一场景,基于原有的话题和服务,设计了动作(Action)这一通信方式来解决这一问题。

这种通信机制的目的就是便于对机器人某一完整行为的流程进行管理

举个例子

举个例子,比如我们想让机器人转个圈,这肯定不是一下就可以完成的,机器人得一点一点旋转,直到360度才能结束,假设机器人并不在我们眼前,发出指令后,我们根本不知道机器人到底有没有开始转圈,转到哪里了?

在这里插入图片描述
OK,现在我们需要的是一个反馈,比如每隔1s,告诉我们当前转到多少度了,10度、20度、30度,一段时间之后,到了360度,再发送一个信息,表示动作执行完成。

这样一个需要执行一段时间的行为,使用动作的通信机制就更为合适,就像装了一个进度条,我们可以随时把控进度,如果运动过程当中,我们还可以随时发送一个取消运动的命令。

客户端/服务器模型

动作和服务类似,使用的也是客户端和服务器模型,客户端发送动作的目标,想让机器人干什么,服务器端执行动作过程, 控制机器人达到运动的目标,同时周期反馈动作执行过程中的状态。

请添加图片描述
客户端发送一个运动的目标,想让机器人动起来,服务器端收到之后,就开始控制机器人运动,一边运动,一边反馈当前的状态,如果是一个导航动作,这个反馈可能是当前所处的坐标,如果是机械臂抓取,这个反馈可能又是机械臂的实时姿态。当运动执行结束后,服务器再反馈一个动作结束的信息。整个通信过程就此结束。

一对多通信

和服务一样,动作通信中的客户端可以有多个,大家都可以发送运动命令,但是服务器端只能有一个,毕竟只有一个机器人,先执行完成一个动作,才能执行下一个动作。

同步通信

既然有反馈,那动作也是一种同步通信机制,之前我们也介绍过,动作过程中的数据通信接口,使用.action文件进行定义。

由服务和话题合成

大家再仔细看下上边的动图,是不是还会发现一个隐藏的秘密。

动作的三个通信模块,竟然有两个是服务,一个是话题,当客户端发送运动目标时,使用的是服务的请求调用,服务器端也会反馈一个应带,表示收到命令。动作的反馈过程,其实就是一个话题的周期发布,服务器端是发布者,客户端是订阅者。

没错,动作是一种应用层的通信机制,其底层就是基于话题和服务来实现的。

感受Action

(1)启动乌龟模拟器和键盘控制节点

  • 乌龟模拟器:
$ ros2 run turtlesim turtlesim_node
  • 键盘控制节点:
$ ros2 run turtlesim turtle_teleop_key
使用方向键移动乌龟。
用G、B、V、C、D、E、R、T键旋转到绝对方向。'F'可以取消旋转。

这段提示什么意思呢?其实就是字面的意思,小乌龟键盘控制节点,提供两种可选的控制方式。

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

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

  • 在小乌龟的遥控窗口我们使用键盘上的F按键周围的按键来尝试运行控制下小乌龟的方向,你会看到小乌龟根据我们所按下按键所在的方向来在原地进行旋转
  • 同时在旋转的过程中,我们可以使用F按键,来取消小乌龟的运动

Action的命令行工具

(1)获取目前系统中的action列表:

$ ros2 action list #获取目前系统中的action列表
/turtle1/rotate_absolute
$ ros2 action list -t    #获取action的类型
/turtle1/rotate_absolute [turtlesim/action/RotateAbsolute]
$ 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

(2)查看action信息:action info

$ ros2 action info /turtle1/rotate_absolute  #获取action客户端和服务段的数量以及名字
Action: /turtle1/rotate_absolute
Action clients: 1
    /teleop_turtle
Action servers: 1
    /turtlesim

(3)发送actin请求到服务端:action send_goal

$ 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.6

Goal accepted with ID: b215ad060899444793229171e76481c7

Result:
    delta: -1.5840003490447998

Goal 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.5

Feedback:
    remaining: -0.0840003490447998

Goal accepted with ID: b368de0ed1a54e00890f1b078f4671c8

Feedback:
    remaining: -0.06800031661987305

Feedback:
    remaining: -0.05200028419494629

Feedback:
    remaining: -0.03600025177001953

Feedback:
    remaining: -0.020000219345092773

Feedback:
    remaining: -0.004000186920166016

Result:
    delta: 0.08000016212463379

Goal finished with status: SUCCEEDED

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

自定义通信接口

目标:控制机器人移动到点

创建接口功能包

创建功能包

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/action
touch src/robot_control_interfaces/action/MoveRobot.action

packages.xml

  <depend>rosidl_default_generators</depend>
  <member_of_group>rosidl_interface_packages</member_of_group>

CMakeLists.txt

find_package(ament_cmake REQUIRED)
find_package(rosidl_default_generators REQUIRED)


rosidl_generate_interfaces(${PROJECT_NAME}
  "action/MoveRobot.action"
)

编写接口

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

编译生成接口

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

代码实现

RCLCPP实现

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值