ROS2 学习(五)接口,动作

接口

通信双方统一规定好接口。比如图像 img,控制运动的线速度和角速度……

我们也不用了解具体实现,基本就是了解接口会去用就行。

1692625169102

$ ros2 interface list # 展示所有 interfaces
$ ros2 interface show ... # 显示具体一个 interface
$ ros2 package show ... # 查看一个 package 里所有的 interface

添加接口

不是说我们写一个接口文件就算添加好了,我们也要通过读取文件。

在 CMakeList.txt 中可以看到:

rosidl_generate_interfaces(${PROJECT_NAME}"msg/ObjectPosition.msg""srv/AddTwoInts.srv""srv/GetObjectPosition.srv""action/MoveCircle.action")

指从相应的相对目录文件中找接口。

在文件中使用对应接口时,则需要先引入:

from File_Path import interface_name

这个引入文件的路径位于系统生成的 .py 文件中,编译成功即生成。

后面创建对象的时候就可以使用接口了。

动作

比如想让小乌龟转一圈,我们需要不停发送指令,根据当前状态调整指令,在一定条件时取消指令。使用动作比这样一点点写服务方便得多。

实际使用的时候我们也很少直接用话题和服务,都是用封装好的动作接口。

动作就是可以一边发运动指令,一边收到反馈信息。

实现方法还是基于话题和服务,话题是服务端(比如要控制运动的机器人)周期性反馈当前状态,服务是客户端给服务端发的指令请求。

比如打开小乌龟,打开键盘控制后,我们可以尝试发送如下指令:

$ ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: 3.14}"
$ ros2 action send_goal /turtle1/rotate_absolute turtlesim/action/RotateAbsolute "{theta: 0}" --feedback 

在接口中可以看到动作接口的三部分:发起动作的目标,动作完成的结束标志,动作的反馈状态。

添加动作

前面的步骤和添加接口一样,编写对应 .action 文件,在 CMakeList.txt 中添加。

服务端:在程序里注意如何添加 action_server:

import rclpy                                      # ROS2 Python接口库
from rclpy.node   import Node                     # ROS2 节点类
from rclpy.action import ActionServer             # ROS2 动作服务器类
from learning_interface.action import MoveCircle  # 自定义的圆周运动接口class MoveCircleActionServer(Node):def __init__(self, name):super().__init__(name)                   # ROS2节点父类初始化self._action_server = ActionServer(      # 创建动作服务器(接口类型、动作名、回调函数)self,MoveCircle,'move_circle',self.execute_callback)def execute_callback(self, goal_handle):            # 执行收到动作目标之后的处理函数self.get_logger().info('Moving circle...')feedback_msg = MoveCircle.Feedback()            # 创建一个动作反馈信息的消息for i in range(0, 360, 30):                     # 从0到360度,执行圆周运动,并周期反馈信息feedback_msg.state = i                      # 创建反馈信息,表示当前执行到的角度self.get_logger().info('Publishing feedback: %d' % feedback_msg.state)goal_handle.publish_feedback(feedback_msg)  # 发布反馈信息time.sleep(0.5)goal_handle.succeed()                           # 动作执行成功result = MoveCircle.Result()                    # 创建结果消息result.finish = True                            return result                                   # 反馈最终动作执行的结果def main(args=None):                                       # ROS2节点主入口main函数rclpy.init(args=args)                                  # ROS2 Python接口初始化node = MoveCircleActionServer("action_move_server")    # 创建ROS2节点对象并进行初始化rclpy.spin(node)                                       # 循环等待ROS2退出node.destroy_node()                                    # 销毁节点对象rclpy.shutdown()                                       # 关闭ROS2 Python接口

反馈函数每30度标记一次发布反馈信息。

客户端:先启动,然后发送动作请求并注册自己的回调函数、收到目标后的回调函数。

from rclpy.action import ActionClient             # ROS2 动作客户端类from learning_interface.action import MoveCircle  # 自定义的圆周运动接口class MoveCircleActionClient(Node):def __init__(self, name):super().__init__(name)                   # ROS2节点父类初始化self._action_client = ActionClient(      # 创建动作客户端(接口类型、动作名)self, MoveCircle, 'move_circle') def send_goal(self, enable):                 # 创建一个发送动作目标的函数goal_msg = MoveCircle.Goal()             # 创建一个动作目标的消息goal_msg.enable = enable                 # 设置动作目标为使能,希望机器人开始运动self._action_client.wait_for_server()    # 等待动作的服务器端启动self._send_goal_future = self._action_client.send_goal_async(   # 异步方式发送动作的目标goal_msg,                                                   # 动作目标feedback_callback=self.feedback_callback)                   # 处理周期反馈消息的回调函数self._send_goal_future.add_done_callback(self.goal_response_callback) # 设置一个服务器收到目标之后反馈时的回调函数def goal_response_callback(self, future):           # 创建一个服务器收到目标之后反馈时的回调函数goal_handle = future.result()                   # 接收动作的结果if not goal_handle.accepted:                    # 如果动作被拒绝执行self.get_logger().info('Goal rejected :(')returnself.get_logger().info('Goal accepted :)')                            # 动作被顺利执行self._get_result_future = goal_handle.get_result_async()              # 异步获取动作最终执行的结果反馈self._get_result_future.add_done_callback(self.get_result_callback)   # 设置一个收到最终结果的回调函数 def get_result_callback(self, future):                                    # 创建一个收到最终结果的回调函数result = future.result().result                                       # 读取动作执行的结果self.get_logger().info('Result: {%d}' % result.finish)                # 日志输出执行结果def feedback_callback(self, feedback_msg):                                # 创建处理周期反馈消息的回调函数feedback = feedback_msg.feedback                                      # 读取反馈的数据self.get_logger().info('Received feedback: {%d}' % feedback.state) def main(args=None):                                       # ROS2节点主入口main函数rclpy.init(args=args)                                  # ROS2 Python接口初始化node = MoveCircleActionClient("action_move_client")    # 创建ROS2节点对象并进行初始化node.send_goal(True)                                   # 发送动作目标rclpy.spin(node)                                       # 循环等待ROS2退出node.destroy_node()                                    # 销毁节点对象rclpy.shutdown()                                       # 关闭ROS2 Python接口

发送动作请求成功了,服务器端先发一个应答反馈,触发的是 goal_response_callback 中的 ‘Goal accepted 😃’ ,后续收到反馈信息是输出 (‘Received feedback: {%d}’ .

$ ros2 run learning_action action_move_server 
[INFO] [1692636260.811751032] [action_move_server]: Moving circle...
[INFO] [1692636260.812184742] [action_move_server]: Publishing feedback: 0
[INFO] [1692636261.313871989] [action_move_server]: Publishing feedback: 30
[INFO] [1692636261.817491663] [action_move_server]: Publishing feedback: 60
[INFO] [1692636262.319652946] [action_move_server]: Publishing feedback: 90
[INFO] [1692636262.822605205] [action_move_server]: Publishing feedback: 120
[INFO] [1692636263.325196016] [action_move_server]: Publishing feedback: 150
[INFO] [1692636263.826669745] [action_move_server]: Publishing feedback: 180
[INFO] [1692636264.328210660] [action_move_server]: Publishing feedback: 210
[INFO] [1692636264.829900461] [action_move_server]: Publishing feedback: 240
[INFO] [1692636265.331746904] [action_move_server]: Publishing feedback: 270
[INFO] [1692636265.833479902] [action_move_server]: Publishing feedback: 300
[INFO] [1692636266.335957841] [action_move_server]: Publishing feedback: 330$ ros2 run learning_action action_move_client 
[INFO] [1692636260.807239104] [action_move_client]: Goal accepted :)
[INFO] [1692636260.815466218] [action_move_client]: Received feedback: {0}
[INFO] [1692636261.315441690] [action_move_client]: Received feedback: {30}
[INFO] [1692636261.820438299] [action_move_client]: Received feedback: {60}
[INFO] [1692636262.320808661] [action_move_client]: Received feedback: {90}
[INFO] [1692636262.827049792] [action_move_client]: Received feedback: {120}
[INFO] [1692636263.326864092] [action_move_client]: Received feedback: {150}
[INFO] [1692636263.827891348] [action_move_client]: Received feedback: {180}
[INFO] [1692636264.332103011] [action_move_client]: Received feedback: {210}
[INFO] [1692636264.831075874] [action_move_client]: Received feedback: {240}
[INFO] [1692636265.332972986] [action_move_client]: Received feedback: {270}
[INFO] [1692636265.834606029] [action_move_client]: Received feedback: {300}
[INFO] [1692636266.337943178] [action_move_client]: Received feedback: {330}
[INFO] [1692636266.848281638] [action_move_client]: Result: {1}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/52369.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

搭建CFimagehost私人图床,实现公网远程访问的详细指南

文章目录 1.前言2. CFImagehost网站搭建2.1 CFImagehost下载和安装2.2 CFImagehost网页测试2.3 cpolar的安装和注册 3.本地网页发布3.1 Cpolar临时数据隧道3.2 Cpolar稳定隧道(云端设置)3.3.Cpolar稳定隧道(本地设置) 4.公网访问测…

PMP证书的正确打开方式 get✓

在职场竞争日益激烈的今天,拥有一项专业认证成为了许多人提升自身竞争力的必备条件。而作为项目管理领域的顶级认证,PMP证书备受关注。不过,很多人对于PMP证书的费用颇有顾虑。那么,PMP证书有什么补贴政策呢?下面就为大…

RTSP/Onvif视频服务器EasyNVR安防视频云服务调用接口录像会被自动删除的问题解决方案

EasyNVR安防视频云服务是基于RTSP/Onvif协议接入的视频平台,可支持将接入的视频流进行全平台、全终端的分发,分发的视频流包括RTSP、RTMP、HTTP-FLV、WS-FLV、HLS、WebRTC等。平台丰富灵活的视频能力,可应用在智慧校园、智慧工厂、智慧水利等…

Hugo托管到Github Pages

Github通过其Github Pages服务可以user、project或organization提供免费快速的静态托管,同时使用Github Actions自动化开发工作流和构建。 1.创建Github仓库 可见性为public。 命名为username.github.io,username为你的Github用户名。 2.添加远程仓库…

vue3-ts- element-plus新增组件-过滤

新增组件-所有值为空时过滤 <el-form-item label"家庭成员"><divclass"username-box"v-for"(item, index) in form.namelist":key"index"><div>姓名&#xff1a;<el-input v-model"item.name" placeho…

Docker的革命:容器技术如何重塑软件部署之路

引言 在过去的几年中&#xff0c;容器技术已经从一个小众的概念发展成为软件开发和部署的主流方法。Docker&#xff0c;作为这一变革的先驱&#xff0c;已经深深地影响了我们如何构建、部署和运行应用程序。本文将探讨容器技术的起源&#xff0c;Docker如何崛起并改变了软件部…

Lombok生成的Getter和Setter的名称对于“eMail”或“xAxis”等属性存在大小写转换异常

问题 最新开发中&#xff0c;遇到一个字段映射问题。我们先看问题案例&#xff1a; 明明代码中第二个字母是大写&#xff0c;结果测试接口时发现变成了小写字母。 分析 通过网上查询发现&#xff0c;这属于Lombok的bug。而且早在2015年就有人在GitHub上提出了issues。 Names o…

基于spring boot校园疫情信息管理系统/疫情管理系统

摘要 随着计算机技术&#xff0c;网络技术的迅猛发展&#xff0c;Internet 的不断普及&#xff0c;网络在各个领域里发挥了越来越重要的作用。特别是随着近年人民生活水平不断提高&#xff0c;校园疫情信息管理系统给学校带来了更大的帮助。 由于当前疫情防控形势复杂&#xff…

贪心算法:简单而高效的优化策略

在计算机科学中&#xff0c;贪心算法是一种简单而高效的优化策略&#xff0c;用于解决许多组合优化问题。虽然它并不适用于所有问题&#xff0c;但在一些特定情况下&#xff0c;贪心算法能够产生近似最优解&#xff0c;而且计算成本较低。在本文中&#xff0c;我们将深入探讨贪…

C++中机器人应用程序的行为树(ROS2)

马库斯布赫霍尔茨 一、说明 以下文章为您提供了对机器人应用程序或框架中经常使用的行为树的一般直觉&#xff1a;ROS&#xff0c;Moveit和NAV2。了解行为 Tress &#xff08;BT&#xff09; 框架的原理为您提供了在游戏领域应用知识的绝佳机会。BT可以与Unity或Unreal集成。 由…

在VS中使用格式化工具

在VS中使用格式化工具 官网地址: https://clang.llvm.org/ 最后更新时间&#xff1a;2023.8.25 这里以windows为例&#xff0c;使用的环境为VS。 &#xff08;一&#xff09;下载安装LLVM 下载地址: https://github.com/llvm安装&#xff08;自己选择安装路径&#xff09; &…

【Azure】Virtual Hub vWAN

虚拟 WAN 文档 Azure 虚拟 WAN 是一个网络服务&#xff0c;其中整合了多种网络、安全和路由功能&#xff0c;提供单一操作界面。 我们主要讨论两种连接情况&#xff1a; 通过一个 vWAN 来连接不通的 vNET 和本地网络。以下是一个扩展的拓扑 结合 vhub&#xff0c;可以把两个中…

深入理解Linux内核--Ext2和Ext3文件系统

Ext2的一般特征 类Unix操作系统使用多种文件系统。尽管所有这些文件系统都有少数POSIX API(如state())所需的共同的属性子集&#xff0c;但每种文件系统的实现方式是不同的。 Linux的第一个版本是基于MINIX文件系统的。当Linux成熟时&#xff0c;引入了扩展文件系统(Extended …

Java smslib包开发

上一篇文章我详细介绍RXTXcomm的安装方法和简单代码,如果小伙伴涉及到需要使用手机短信模块完成短信收发需求的话,可以使用到smslib进行开发。 首先还是同样的,将整个smslib包源码导入项目,并且将它所需依赖一起进行导入 导入完成之后,我们就可以对smslib包进行二次开发了 下面…

SensorService中Binder案例

SensorService中Binder案例 1、FWK实际操作在Native层2、Native层中代码实现Bn/Bp端2.1 代码实现Bn端2.2 代码实现Bp端2.2.1 模板interface_cast android12-release 1、FWK实际操作在Native层 SensorService.java实际操作Native层SensorService.cpp&#xff1b;对应Bn服务端。 …

微信小程序 车牌号输入组件

概述 一个小组件&#xff0c;用于方便用户输入车牌号码 详细 概述 有时候我们开发过程中会遇到需要用户输入车牌号的情况&#xff0c;让客户通过自带键盘输入&#xff0c;体验不好且容易出错&#xff0c;例如车牌号是不能输入O和I的&#xff0c;因此需要有一个自定义的键盘…

vue直接使用高德api

第一步&#xff1a;在index.html 引入 <script src"https://webapi.amap.com/maps?v2.0&key你的key"></script>第二步&#xff1a;在你需要地图的时候 放入 <template><div style"width: 200px; height: 200px"><div id&q…

极狐GitLab 价值流管理之「总时间图」使用指南

本文来源&#xff1a;about.gitlab.com 作者&#xff1a;Haim Snir 译者&#xff1a;极狐(GitLab) 市场部内容团队 对于软件研发管理者来说&#xff0c;了解在整个研发过程中时间都耗费在了哪些地方&#xff0c;是进行交付价值优化的关键洞察。GitLab / 极狐GitLab 新的价值流分…

回归预测 | MATLAB实现PSO-RBF粒子群优化算法优化径向基函数神经网络多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现PSO-RBF粒子群优化算法优化径向基函数神经网络多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09; 目录 回归预测 | MATLAB实现PSO-RBF粒子群优化算法优化径向基函数神经网络多输入单输出回归预测&#xff08;多指标&#xff0c;多图&a…

创建和分析二维桁架和梁结构研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…