Action(动作通信Python)

2023-05-16

        机器人导航到某个目标点,此过程需要一个节点A发布目标信息,然后一个节点B接收到请求并控制移动,最终响应目标达成状态信息。

        乍一看,这好像是服务通信实现,因为需求中要A发送目标,B执行并返回结果,这是一个典型的基于请求响应的应答模式,不过,如果只是使用基本的服务通信实现,存在一个问题:导航是一个过程,是耗时操作,如果使用服务通信,那么只有在导航结束时,才会产生响应结果,而在导航过程中,节点A是不会获取到任何反馈的,从而可能出现程序"假死"的现象,过程的不可控意味着不良的用户体验,以及逻辑处理的缺陷(比如:导航中止的需求无法实现)。更合理的方案应该是:导航过程中,可以连续反馈当前机器人状态信息,当导航终止时,再返回最终的执行结果。在ROS中,该实现策略称之为:action 通信。

        在ROS中提供了actionlib功能包集,用于实现 action 通信。action 是一种类似于服务通信的实现,其实现模型也包含请求和响应,但是不同的是,在请求和响应的过程中,服务端还可以连续的反馈当前任务进度,客户端可以接收连续反馈并且还可以取消任务。

 1.定义action文件

        首先新建功能包,并导入依赖: roscpp rospy std_msgs actionlib_msgs

        然后功能包下新建 action 目录,新增 Timer.action。

        action 文件内容组成分为三部分:请求目标值、最终响应结果、连续反馈,三者之间使用---分割示例内容如下:

# This is an action definition file, which has three parts: the goal, the
# result, and the feedback.
#
# Part 1: the goal, to be sent by the client
#
# The amount of time we want to wait
duration time_to_wait
---
# Part 2: the result, to be sent by the server upon completion
#
# How much time we waited
duration time_elapsed
# How many updates we provided along the way
uint32 updates_sent
---
# Part 3: the feedback, to be sent periodically by the server during
# execution.
#
# The amount of time that has elapsed from the start
duration time_elapsed
# The amount of time remaining until we're done
duration time_remaining

2.编辑配置文件CMakeLists.txt

find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  actionlib_msgs
)
## Generate actions in the 'action' folder
add_action_files(
  FILES
  Timer.action
)

## Generate added messages and services with any dependencies listed here
generate_messages(
  DEPENDENCIES
  actionlib_msgs
  std_msgs
)
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES demo_action
CATKIN_DEPENDS actionlib_msgs roscpp rospy std_msgs
#  DEPENDS system_lib
)
catkin_install_python(PROGRAMS
  # scripts/simple_action_server.py
  # scripts/simple_action_client.py
  scripts/fancy_action_server.py
  scripts/fancy_action_client.py
  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

3.vscode配置

配置settings.json文件包含python文件所在路径,我的配置如下(主要看第九行

{
    "python.autoComplete.extraPaths": [
        "/home/ssz/demo15_server_client/devel/lib/python2.7/dist-packages",
        "/home/ssz/demo14_pub_sub/devel/lib/python2.7/dist-packages",
        "/home/ssz/demo12_ws/devel/lib/python2.7/dist-packages",
        "/home/ssz/demo09_ws/devel/lib/python2.7/dist-packages",
        "/home/ssz/demo08_ws/devel/lib/python2.7/dist-packages",
        "/opt/ros/melodic/lib/python2.7/dist-packages",
        "/home/ssz/demo18_action/devel/lib/python2.7/dist-packages"
    ],
    "python.analysis.extraPaths": [
        "/home/ssz/demo15_server_client/devel/lib/python2.7/dist-packages",
        "/home/ssz/demo14_pub_sub/devel/lib/python2.7/dist-packages",
        "/home/ssz/demo12_ws/devel/lib/python2.7/dist-packages",
        "/home/ssz/demo09_ws/devel/lib/python2.7/dist-packages",
        "/home/ssz/demo08_ws/devel/lib/python2.7/dist-packages",
        "/opt/ros/melodic/lib/python2.7/dist-packages"
    ]
}

服务端

#! /usr/bin/env python
# -*- coding:utf-8 -*-
import rospy
import time
import actionlib
from demo_action.msg import TimerAction,TimerGoal,TimerResult,TimerFeedback

def do_timer(goal):
        start_time = time.time()
        # 统计总共发布多少反馈信息
        update_count = 0

        if goal.time_to_wait.to_sec() > 60.0:
            result = TimerResult()
            result.time_elapsed = rospy.Duration.from_sec(time.time() - start_time)
            result.updates_sent = update_count
            server.set_aborted(result,"Timer aborted due to too-long wait")
            return
        while (time.time()-start_time) < goal.time_to_wait.to_sec():
            if server.is_preempt_requested():
                result = TimerResult()
                result.time_elapsed = rospy.Duration.from_sec(time.time()-start_time)
                result.updates_sent = update_count
                server.set_preempted(result,"Timer preempted")
                return
            
            feedback = TimerFeedback()
            feedback.time_elapsed = rospy.Duration.from_sec(time.time() - start_time)
            feedback.time_remaining = goal.time_to_wait - feedback.time_elapsed
            server.publish_feedback(feedback)
            update_count += 1
            # 进行短暂的休眠,下面代码采用的“固定休眠时长”方法虽然简单,但其实并不好,
            # 因为这样很容易导致实际休眠时长超过请求时长的问题。
            time.sleep(1.0)
        
        result = TimerResult()
        result.time_elapsed = rospy.Duration.from_sec(time.time() - start_time)
        result.updates_sent = update_count
        # 增加了一个状态字符串
        server.set_succeeded(result,"Timer completed successfully")

rospy.init_node("fancy_action_server")
server = actionlib.SimpleActionServer("timer",TimerAction,do_timer,False)
server.start()
rospy.spin()

客户端

#! /usr/bin/env python
# -*- coding:utf-8 -*-
import rospy
import time
import actionlib
from demo_action.msg import TimerAction,TimerGoal,TimerResult,TimerFeedback

def feedback_cb(feedback):
    print("[Feedback] Time elapsed: %f" %(feedback.time_elapsed.to_sec()))
    print("[Feedback] Time remaining: %f" %(feedback.time_remaining.to_sec()))

rospy.init_node("time_action_client")
client = actionlib.SimpleActionClient("timer",TimerAction)
client.wait_for_server()
goal = TimerGoal()
goal.time_to_wait = rospy.Duration.from_sec(5.0)
# 测试请求时长超过60s的情形
# goal.time_to_wait = rospy.Duration.from_sec(500.0)

# 将回调函数作为feedback-cb关键词的参数,传入send_goal()中,完成回调的注册
client.send_goal(goal,feedback_cb=feedback_cb)

# 测试目标中断
# time.sleep(3.0)
# client.cancel_goal()

client.wait_for_result()
# 在接收到结果之后,我们打印了一些信息来显示当前的状态。get_stste()函数返回本次目标对应的执行结果,
# 类型为actionlib_mags/GoalStatus。可能的状态有10种
# 终端运行rosmsg info actionlib_msgs/GoalStatus命令,看到以下10种
# uint8 PENDING=0
# uint8 ACTIVE=1
# uint8 PREEMPTED=2
# uint8 SUCCEEDED=3
# uint8 ABORTED=4
# uint8 REJECTED=5
# uint8 PREEMPTING=6
# uint8 RECALLING=7
# uint8 RECALLED=8
# uint8 LOST=9
# actionlib_msgs/GoalID goal_id
#   time stamp
#   string id
# uint8 status
# string text
# 此处只考虑其中三种:PREEMPTED=2、SUCCEEDED=3、ABORTED=4
# 除此之外还打印了服务端发送的状态字符串
print("[Result] State: %d" %(client.get_state()))
print("[Result] Status: %s" %(client.get_goal_status_text()))
print("[Result] Time elapsed: %f" %(client.get_result().time_elapsed.to_sec()))
print("[Result] Updates sent: %d" %(client.get_result().updates_sent))

 功能检查

先启动roscore,终端运行下面指令

可以看到所有节点运行起来了:等待过程中,每秒会收到一次反馈。等待结束后,会收到目标执行成功的结果(SUCCEED = 3)。

现在试试中断一个执行中的目标。在客户端代码的send_goal()调用后对下面两行解除注释,这样会让客户端在短暂的休眠后中断当前的目标。

# 测试目标中断
# time.sleep(3.0)
# client.cancel_goal()

 再次运行客户端

表现出的行为与预期吻合:服务器首先执行最开始的目标,并定时进行反馈,直到客户端发出了终止请求。发出终止请求后,客户端很快就收到了服务端发来的结果,表明上一次执行被中断(PREEMPTED = 2)

现在来引发一个服务端的主动终止。在客户端代码中,对下面的代码解除注释,将等待时间从5s改为500s.

# 测试请求时长超过60s的情形
# goal.time_to_wait = rospy.Duration.from_sec(500.0)

再次运行客户端

服务端立即主动终止了目标的执行(ABORTED = 4)

话题、服务和动作机制的对比
类型最佳使用场景
话题单工通信,尤其是接收方有多个时(如传感器数据流)
服务简单的请求/响应式交互场景,如询问节点的当前状态
动作大部分请求/响应式交互场景,尤其是执行过程不能立即完成时(如导航前往另一个目标点、机械臂移动)

综合上文中提到的所有特性,动作机制在机器人编程的许多方面都很适合。在机器人应用中,执行一个时长不定,目标引导新的任务是很常见的,无论是goto_position,还是clean_the_house。在任何情况下,当需要执行一个任务时,动作都可能时最正确的选择。事实上,每当你想要使用服务时,都值的考虑一下是否可以替换为动作。虽然使用动作需要写更多的代码,但是却比服务更强大,扩展性更好。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Action(动作通信Python) 的相关文章

  • GDI GDI+ 的区别

    转载自 xff1a http www cnblogs com lidabo p 3701252 html GDI 43 是GDI的下一个版本 xff0c 它进行了很好的改进 xff0c 并且易用性更好 GDI的一个好处就是你不必知道任何关于
  • 使用的DockPanel的心得

    使用这个控件的时候后一定要先Show this DockPlan1 才能使用DockTo this DockPlan1 DockStyle Bottom 固定位置 xff0c 否则会抛出异常
  • C#使用双缓冲解决绘图闪屏的问题

    最近在工作需要使用C 绘制图形 xff0c 看了一下绘制的函数觉得很简单就开始着手工作了 xff0c 但是在实际应用的时候发现鼠标进行绘制的时候会闪屏 xff0c 原因是图元重绘的时间不一致 xff0c 百度一下有很多更详细的 xff0c
  • 关于捕获键盘信息的processDialogkey方法

    转载自 xff1a http blog csdn net lucifinil s article details 6318189 在一些控件里的keydown方法 xff0c 没有办法捕获所有的按键消息 比如自己写一个窗体控件库 xff0c
  • C#泛型委托

    因为项目原因最近要使用C 进行编程 xff0c 于是每天现学现卖一点一点的进行开发 之前很长的时间一直使用C和C 43 43 进行编程 xff0c 于是转到C 一开始开始不是特别适应的 xff0c 特别是C 这门语言没有了指针 xff0c
  • 基于windows的Ubuntu双系统安装

    Data 2016 12 19 Author cjh Theme Ubuntu dual system installation 前期准备 1 Ubuntu相关版本镜像ios 2 UltraISO 用于制作U盘启动盘 3 EasyBCD 2
  • 汇编文件.S和.s的区别

    c C 原始程序 xff1b 预处理 编译 汇编 C C 43 43 原始程序 xff1b 预处理 编译 汇编 ccC 43 43 原始程序 xff1b 预处理 编译 汇编 cxx C 43 43 原始程序 xff1b 预处理 编译 汇编
  • 串口网口数据帧解析(支持连包、断传、错误数据过滤)

    本文转载自 xff1a https blog csdn net hwb 1988 article details 45872379 嵌入式系统中 xff0c 关于数据接受部分确实思考了很多 xff0c 下面总结下个人经验 关于串口传输 xf
  • Use of $Super$ $  and$Sub$ $to patch symbol definitions

    在无法修改现有符号的情况下 xff0c 可以使用特殊模式 现有符号无法修改 xff0c 例如 xff0c 如果它位于外部库或ROM代码中 在这种情况下 xff0c 您可以使用 Super 和 Sub 模式来修补现有符号 修补函数foo xf
  • RT-Thread内核移植

    记录代码移植过程 xff0c 成功一步记录一步 第一步 xff1a 建立裸机程序 使用STM32CubeMx建立一个裸机程序 生成MDK5工程 第二步 xff1a 参考0 bare metal完成board c board h文件 在Dri
  • C#委托和事件框架封装简写 delegate、event、Action、EventHandler

    曾经 Net大佬只有一个Delegete 委托 xff0c 别人想用委托的时候 xff0c 必须得用delegate关键字来定义一个委托 xff0c 就像这样 span class token comment 定义一个无返回值的 xff0c
  • CentOS 7 firewalld使用简介

    学习apache安装的时候需要打开80端口 xff0c 由于centos 7版本以后默认使用firewalld后 xff0c 网上关于iptables的设置方法已经不管用了 xff0c 想着反正iptable也不会用 xff0c 索性直接搬
  • 通过VNC访问docker容器的图形界面

    https hub docker com r dorowu ubuntu desktop lxde vnc https github com fcwu docker ubuntu vnc desktop docker ubuntu vnc
  • 阿里云产品图标

    2022年最新 最全的阿里云产品图标 xff0c 矢量图哦 xff0c 留下你的邮箱 xff0c 我发给你 2022年最新阿里云产品图标 有200多个图标 随时可以拿来用 为了可以审批通过 我在这里多写点字 我平时都是用这些图标 用来做设计
  • 论文引用:参考文献GB/T 7714、APA、MLA的自动生成

    一 谷歌学术 1 谷歌学术镜像 xff1a 谷歌学术镜像 Google学术搜索导航 64 思谋学术 xff0c 随意点进去一个链接 2 搜索需要的论文 xff0c 点击下方引用小标志 3 根据自己需要的引用标准 xff0c 选择复制 注 x
  • 人工智能与安全论坛:智能与安全的融合与对抗

    前几天随公司参加了互联网安全大会 xff08 ISC xff0c Internet Security Conference xff09 xff0c 虽然只参加了半天的会议 xff0c 感觉收获不 更重要的是偶遇师兄 xff0c 人生无处不相
  • Jetson TX1刷机历险记

    Data 2016 12 19 Author cjh Theme Jetson TX1 Brush 这两天刚到了英伟达的jetson tx1 开发板 xff0c 之前也看了写资料 xff0c 感觉应该很充分刷机应该没有问题才对 xff0c
  • curl: (7) Failed to connect to raw.githubusercontent.com port 443: Connection refused 解决方法

    问题 xff1a 报错 curl 7 Failed to connect to raw githubusercontent com port 443 Connection refused 解决方法 xff1a 参考 xff1a https
  • GailHoward

    全球著名彩票预测家美国人 xff27 xff41 xff49 xff4c xff28 xff4f xff57 xff41 xff52 xff44 发明的 旋转系统 选号法已经造就了 xff17 xff14 个大奖得主 xff0c 这是一种基
  • Casbin Demo实例(支持CSV和MySQL两种策略规则)

    Casbin 帮助文档地址 xff1a https casbin org docs zh CN how it works 常见的设计模式 xff08 DAC xff0c MAC xff0c RBAC xff0c ABAC xff09 0 基

随机推荐

  • Ubuntu下分别用gcc和makefile编译C语言

    Ubuntu下分别用gcc和makefile编译C语言 1 编写C文件2 gcc编译C文件3 makefile编译C文件3 1 创建makefile文件3 2 编译makefile文件 4 总结 在Windows环境下通过虚拟机软件 xff
  • px4 守护进程高频获取uorb消息

    任务 xff0c 需要通过后台进程持续的以一定频率 xff0c 获取uorb某个主题的数据 xff0c 因此必须通过守护进程的方式 xff0c 不能中断终端调用其他程序 守护进程可以参考module里面都是用守护进程的方式来跑功能的 xff
  • UDA/语义分割-ColorMapGAN: Unsupervised Domain Adaptation for Semantic Segmentation Using Color Mapping G

    ColorMapGAN Unsupervised Domain Adaptation for Semantic Segmentation Using Color Mapping Generative Adversarial Networks
  • 目标检测正负样本区分和平衡策略(anchor-based)

    最近看了一篇大佬写关于正负样本区分和平衡策略的博文 xff0c 研究了一下并且查了一下资料进行了补充 xff0c 加上个人的见解和解读 xff0c 在此做个总结 xff0c 欢迎大家补充指正 xff0c 侵权必删 大佬博文 xff1a 目标
  • voc旋转标注数据转dota类型

    voc旋转标注数据转dota类型 voc2dota pyListFilesToTxt pyroxml to dota py 在cv领域数据集的标注过程中 xff0c 用labelImg工具我们可以对数据进行标注 xff0c 标注生成的voc
  • CVPR2022: Oriented RepPoints论文模型实践(用dota数据集)

    CVPR2022 Oriented RepPoints论文模型实践 xff08 用dota数据集 xff09 论文 xff1a https arxiv org abs 2105 11111 github xff1a https github
  • DM365 adc学习笔记

    Data 2015 11 23 Author cjh Theme DM365 adc Note 数据手册并没有写明ADC 可采集电压的范围 xff0c 但是整个ADC模块的供电电压是1 8V xff0c 并且参照合众达的程序以及原理图 xf
  • python用PIL库批量裁剪指定大小的图像(自动填充裁剪不完的部分)

    概述 主要功能 xff1a 使用python代码裁剪批量图片 网上用python裁剪图片的代码有很多 xff0c 但是往往没有考虑到图片裁剪不完的情况 举个例子 xff0c 我有4096 1800的图片 xff0c 想把它批量裁剪成1024
  • 图像分割mask图上画出目标检测框

    概述 xff1a 最近在做跟语义分割有关的变化检测方向的工作 当遇到模型的输出是一张mask图的情况下 xff0c 单纯用肉眼看检测的效果可能不是很直观 这时我们可以利用python脚本 xff0c 调用opencv的cv2 connect
  • (深度学习)yolo(txt)与voc(xml)格式相互转换脚本

    提供了两个用来将voc格式的xml文件相互转换的简单脚本 xff0c 修改一下class类和文件目录即可使用 voc转yolo xff1a xml2txt py span class token keyword import span os
  • 【Pascal voc格式的xml文件与YOLO格式文件的互相转换图】

    一图了解xml格式与YOLO格式如何相互转换 xff1a 两种格式相互转换的代码可以参考我之前的文章 xff1a https blog csdn net SSSlasH article details 126927858 spm 61 10
  • 51单片机——LED点阵屏(显示滚动画面)

    目录 一 关于数码管 LED点阵屏显示的注意点 二 功能介绍 三 主要模块的介绍 3 1 74HC595模块和点阵屏显示函数 3 1 1 74HC595介绍 3 1 2 点阵屏显示函数MatrixLED 3 2定时器中断模块 四 程序实现
  • JAVA学习记录

    JAVA学习笔记 总结自how2j cn JAVA基础 HelloWorld 下载JDK 配置环境变量 检查配置是否成功java version 创建源文件 编写基础输出命令System out println 34 hello world
  • C# P2P实现点对点聊天

    P2P xff0c 英文Peer to Peer的缩写 xff0c 中译为对等互联或点对点技术 P2P技术可以让用户可以直接连接到其他用户的计算机 xff0c 进行文件共享与交换 xff0c 同时P2P在深度搜索 分布计算 协同工作等方面也
  • 目标检测自动标注python脚本

    在需要大量标注数据时 xff0c 可以先用少量样本训练一个模型 xff0c 在模型大致可以正常输出类别和位置坐标的情况下进行自动标注 xff0c 后续再进行少量的人工调整 xff0c 可以节省很大的精力 xff08 自动标注的格式仿照lab
  • 微博文本分类任务

    数据 借用了这位兄弟的数据 xff0c 4类文本分类问题 xff1a https blog csdn net qq 28626909 article details 80382029 代码参考 预处理工具torchtext学习参考了nlpu
  • Mac 安装Java反编译工具JD-GUI

    一 下载JD GUI软件 1 首先到Github下载JD GUI软件 xff1a github java decompiler jd gui Public 选择jd gui osx 1 6 6 tar 2 解压打开软件 xff0c 但是提示
  • Dm365 VPBE 后端模块讲解

    Data 2016 12 22 Author cjh Theme DM365 explain of VPBE 研一进来先是接触了TI的dm6437 一款DSP处理器 xff0c DaVinci系类主要用于图像及视频的相关处理 xff0c 和
  • ROS服务通信

    1 服务通信 服务通信也是ROS中一种极其常用的通信模式 xff0c 服务通信是基于请求响应模式的 xff0c 是一种应答机制 也即 一个节点A向另一个节点B发送请求 xff0c B接收处理请求并产生响应结果返回给A 比如如下场景 机器人巡
  • Action(动作通信Python)

    机器人导航到某个目标点 此过程需要一个节点A发布目标信息 xff0c 然后一个节点B接收到请求并控制移动 xff0c 最终响应目标达成状态信息 乍一看 xff0c 这好像是服务通信实现 xff0c 因为需求中要A发送目标 xff0c B执行