ROS2从入门到精通1-3:详解ROS2动作通信机制与自定义动作

目录

  • 0 专栏介绍
  • 1 动作通信模型
  • 2 动作模型实现(C++)
  • 3 动作模型实现(Python)
  • 4 自定义动作

0 专栏介绍

本专栏旨在通过对ROS2的系统学习,掌握ROS2底层基本分布式原理,并具有机器人建模和应用ROS2进行实际项目的开发和调试的工程能力。

🚀详情:《ROS2从入门到精通》


1 动作通信模型

在ROS2中,动作通信机制提供了一种用于执行长时间运行任务的方式,由三个部分组成:

  • 目标(goal):对客户端的请求进行处理和响应
  • 反馈(feedback):对监控任务的动作执行过程提供反馈数据
  • 结果(result):对监控任务的执行结果提供反馈

举个机器人导航的任务说明

假设有一个机器人需要从起始点导航到目标点。通过使用动作通信机制,可以定义一个导航动作,其中目标是目标位置。机器人将发送导航目标给动作服务器,服务器将返回连续的反馈,例如机器人的当前位置,障碍物检测等。最终,当机器人到达目标位置时,服务器将返回导航任务的结果。

再比如机械臂控制

通过定义动作目标和提供连续的反馈,可以实现对机械臂的精确控制。例如,可以定义一个动作来控制机械臂移动到特定位置,反馈可以包括当前位置、力传感器的读数等。一旦机械臂到达目标位置,服务器将返回控制任务的结果

在这里插入图片描述

动作是应用级通信机制,建立在话题和服务之上,但却与话题和服务通信不同:

  • 动作通信更适合描述一项任务的执行过程,而话题通信更适合传输实时数据;
  • 动作通信返回一系列的反馈和一个最终结果,而服务通常只返回单个响应;
  • 动作通信是可中断的,即在执行过程中可以取消,而服务通信通常是一次性的请求-响应模式;

总之,通过使用动作通信,可以实现更复杂的交互和反馈,并灵活地处理长时间运行的任务

2 动作模型实现(C++)

实验目标:客户端提交请求给turtlesim功能包的/rotate_absolute动作,在界面上使乌龟旋转,并不断监听乌龟的实时旋转数据,以及到达目标角度的反馈。

  • 服务器

    本实验中无需编程,为turtlesim::Action定义的/rotate_absolute服务

  • 客户端

    1. 注册一个客户端
      client_ptr_ = rclcpp_action::create_client<TurtleAction>(get_node_base_interface(),get_node_graph_interface(),get_node_logging_interface(),get_node_waitables_interface(),"/turtle1/rotate_absolute"
      );
      
    2. 定义目标响应回调函数
      void OnGoalResponseCallback(GoalHandle::SharedPtr goal_message) {if (!goal_message) {RCLCPP_ERROR(get_logger(), "Client: Goal was rejected by server");rclcpp::shutdown();} elseRCLCPP_INFO(get_logger(), "Client: Goal accepted by server, waiting for result");
      }
      
    3. 定义过程反馈回调函数
      void OnFeedbackCallback(GoalHandle::SharedPtr, const std::shared_ptr<const TurtleAction::Feedback> feedback_message) {std::stringstream ss;ss << "Client: Received feedback: " << feedback_message->remaining;RCLCPP_INFO(this->get_logger(), "%s", ss.str().c_str());
      }
      
    4. 定义结果回调函数
      void OnResultCallback(const GoalHandle::WrappedResult & result_message) {switch (result_message.code) {case rclcpp_action::ResultCode::SUCCEEDED:break;case rclcpp_action::ResultCode::ABORTED:RCLCPP_ERROR(get_logger(), "Client: Goal was aborted");rclcpp::shutdown();return;case rclcpp_action::ResultCode::CANCELED:RCLCPP_ERROR(get_logger(), "Client: Goal was canceled");rclcpp::shutdown();return;default:RCLCPP_ERROR(get_logger(), "Client: Unknown result code");rclcpp::shutdown();return;}RCLCPP_INFO(get_logger(), "Client: Result received: %.2f", (result_message.result->delta));rclcpp::shutdown();
      }
      

实验结果如下所示,在本实验中,theta表示发送的目标角度;remaining是过程反馈的目标角度差值信息;delta是结果响应,表示距离初始位置的角度偏差

在这里插入图片描述

3 动作模型实现(Python)

实验目标:客户端提交请求给turtlesim功能包的/rotate_absolute动作,在界面上使乌龟旋转,并不断监听乌龟的实时旋转数据,以及到达目标角度的反馈。

  • 服务器

    本实验中无需编程,为turtlesim::Action定义的/rotate_absolute服务

  • 客户端

    1. 注册一个客户端
      self.client_ = ActionClient(self, RotateAbsolute, '/turtle1/rotate_absolute')
      
    2. 定义目标响应回调函数
      def OnGoalResponseCallback(self, future):goal_handle = future.result()  if not goal_handle.accepted: self.get_logger().info('Client: Goal was rejected by server')returnself.get_logger().info('Client: Goal accepted by server, waiting for result')self._get_result_future = goal_handle.get_result_async()self._get_result_future.add_done_callback(self.OnResultCallback)
      
    3. 定义过程反馈回调函数
      def OnFeedbackCallback(self, feedback_msg):feedback = feedback_msg.feedbackself.get_logger().info(f'Received feedback: {feedback.remaining:.2f}') 
      
    4. 定义结果回调函数
      def OnResultCallback(self, future):if future.done():self.get_logger().info(f'Action done!')result = future.result().resultself.get_logger().info(f'Result: {result.delta:.2f}')elif future.cancelled():self.get_logger().info(f"Client: Goal was canceled")else:raise RuntimeWarning("Client: Unknown result code") 
      

实验结果如下所示,在本实验中,theta表示发送的目标角度;remaining是过程反馈的目标角度差值信息;delta是结果响应,表示距离初始位置的角度偏差

在这里插入图片描述

4 自定义动作

自定义动作的通用流程如下:

  • 功能包下新建action文件夹,在其中添加自定义服务xxx.action,注意目标、反馈和结果数据结构使用---分割
  • 功能包package.xml中添加编译依赖与执行依赖
    <buildtool_depend>rosidl_default_generators</buildtool_depend>
    <exec_depend>rosidl_default_runtime</exec_depend>
    <member_of_group>rosidl_interface_packages</member_of_group>
    
  • 功能包CMakeLists.txt中添加编译消息相关依赖
    find_package(rosidl_default_generators REQUIRED)
    rosidl_generate_interfaces(${PROJECT_NAME}"xxx.action"DEPENDENCIES xxx_actions
    )ament_export_dependencies(rosidl_default_runtime)
    
  • 编译自定义动作,在install/<pkg_name>/include中生成由xxx.action编译的C++可识别的xxx.hpp头文件
  • 引入xxx.hpp即可调用自定义动作

下面给出一个实例

实现一个自定义动作,请求机器人开始圆周运动,反馈机器人的实时运动角度,并返回最终结果

添加如下自定义动作,并按上面步骤配置依赖

bool enable     # goal
---
bool finish     # result
---
int32 state     # feedback

定义一个服务器、一个客户端,限于篇幅只贴出部分代码,完整代码见文末。

  • 服务器
    class OwnActionServerNode : public rclcpp::Node
    {public:using OwnAction = own_action_lab::action::MoveCircle;using GoalHandle = rclcpp_action::ServerGoalHandle<OwnAction>;explicit OwnActionServerNode(const rclcpp::NodeOptions & action_server_options = rclcpp::NodeOptions()): Node("own_action_server", action_server_options) {action_server_ = rclcpp_action::create_server<OwnAction>(get_node_base_interface(),get_node_clock_interface(),get_node_logging_interface(),get_node_waitables_interface(),"/move",std::bind(&OwnActionServerNode::OnHandleGoal, this, std::placeholders::_1, std::placeholders::_2),std::bind(&OwnActionServerNode::OnHandleCancel, this, std::placeholders::_1),std::bind(&OwnActionServerNode::OnHandleAccepted, this, std::placeholders::_1));}
    }
    
  • 客户端
    class OwnActionClientNode : public rclcpp::Node
    {public:using OwnAction = own_action_lab::action::MoveCircle;using GoalHandle = rclcpp_action::ClientGoalHandle<OwnAction>;explicit OwnActionClientNode(const rclcpp::NodeOptions & node_options = rclcpp::NodeOptions()): Node("own_action_client", node_options) {client_ptr_ = rclcpp_action::create_client<OwnAction>(get_node_base_interface(),get_node_graph_interface(),get_node_logging_interface(),get_node_waitables_interface(),"/move");}
    }
    

实测效果如下:

在这里插入图片描述

完整代码通过下方博主名片联系获取


🔥 更多精彩专栏

  • 《ROS从入门到精通》
  • 《Pytorch深度学习实战》
  • 《机器学习强基计划》
  • 《运动规划实战精讲》

👇源码获取 · 技术交流 · 抱团学习 · 咨询分享 请联系👇

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

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

相关文章

【Linux深造日志】运维工程师必会Linux常见命令以及周边知识!

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《linux深造日志》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 引入 哈喽各位宝子们好啊&#xff01;我是博主鸽芷咕。日志这个东西我相信大家都不陌生&#xff0c;在 linxu/Windows 系统…

暖宝轻工机械有限公司现已加入2024第13届生物发酵展

参展企业介绍 公司坐落于富饶的长江三角洲&#xff0c;美丽的瓯越山水---温州&#xff0c;成立20多年来&#xff0c;专业从事换热器新品研发、应用设计、生产制造、销售服务为一体的综合性生产企业。 公司致力于食品、饮料、果酒、制药、暖通、化工等行业领域的加热冷却、蒸发…

微信定时发送指定消息

微信定时发送消息 简介&#xff1a; 该项目为微信定时发送消息机器人&#xff0c;可以扫码登录微信&#xff0c;输入微信好友名称或群聊名称&#xff0c;添加定时任务内容&#xff08;时间、内容、图片&#xff09;&#xff0c;便可在指定时间发送该设置好的内容。 该项目包…

爬虫的目的是做什么

通过网站域名获取HTML数据解析数据&#xff0c;获取想要的信息存储爬取的信息如果有必要&#xff0c;移动到另一个网页重复过程 这本书上的代码的网址是 &#xff1a; GitHub - REMitchell/python-scraping: Code samples from the book Web Scraping with Python http://shop.…

51单片机-独立按键模块

1. 独立按键控制LED状态 轻触按键实现原理&#xff1a;按下时&#xff0c;接通&#xff0c;通过金属弹片受力弹动来实现接通和断开。 松开按键 按下之后&#xff1a;就会被连接 同时按下K1和K2时&#xff0c;P2_0,接口所连LED灯才亮。 #include <REGX52.H> void ma…

linux学习:目录检索

目录 目录 api 例子 目录 Linux 中的目录并不是一种容器&#xff0c;而仅仅是一个文件索引表 Linux 中目录就是一组由文件名和索引号组成的索引表&#xff0c;目录下的文件的真正内容存储 在分区中的数据域区域。目录中索引表的每一项被称为“目录项”&#xff0c;里面至少…

力扣HOT100 - 240. 搜索二维矩阵 II

解题思路&#xff1a; 从左下角开始&#xff0c;根据条件删除行和列。 class Solution {public boolean searchMatrix(int[][] matrix, int target) {int row matrix.length - 1;int col matrix[0].length - 1;int l 0;while (row > 0 && l < col) {if (targ…

MR鼻祖呼吁不要滥用孟德尔随机化法,多数文章没有意义

孟德尔随机化,Mendilian Randomization&#xff0c;简写为MR&#xff0c;是一种在流行病学领域应用广泛的一种实验设计方法&#xff0c;利用公开数据库就能轻装上阵写文章&#xff0c;甚至是高质量的论文。 近几年绝对是发文利器呀&#xff01; 但&#xff0c;最近MR鼻祖&#…

MBTI入侵职场,题目都用大模型生成了?!

宝子们&#xff0c;MBTI测过吗&#xff1f; 什么是MBTI呢&#xff1f;它是一个深入抽丝剥茧的性格测试&#xff0c;它的全称是Myers-Briggs Type Indicator&#xff08;迈尔斯-布里格斯性格指标&#xff09;&#xff0c;它会从四个维度上分析你的行为、喜好和思考方式&#xf…

Eigen库从入门到放弃(2. Getting Started)

Eigen的头文件定义了多种类型&#xff0c;但是对于简单的来说&#xff0c;使用MatrixXd就足够了&#xff0c;MatrixXd表示任意尺寸的矩阵&#xff0c;但是要注意数据类型是double的。Eigen/Dense的头文件定义了所有MatrixXd和相关类型的成员函数。所有头文件中定义的函数都是在…

【论文阅读——SplitFed: When Federated Learning Meets Split Learning】

级别CCFA 1.摘要 联邦学习&#xff08;FL&#xff09;和分割学习&#xff08;SL&#xff09;是两种流行的分布式机器学习方法。两者都采用了模型对数据的场景&#xff1b;客户端在不共享原始数据的情况下训练和测试机器学习模型。由于机器学习模型的架构在客户端和服务器之间…

高中数学:三角函数-4个解题妙招

一、对偶式 1、针对题型 同角三角函数的问题 2、方法定义 对于形如下方的式子&#xff0c;就可以用对偶式方法解 3、练习 例题1 例题2 二、巧用三角函数定义 1、针对题型 没有给出具体三角函数值的问题 2、方法定义 3、练习 例题1 三、诱导公式 1、针对题型 锐…