ARTICLE DETAIL

资讯详情

深耕网站SEO优化与搜索引擎排名提升的一线实战洞察。

ROS2 Action通信实战

ROS2 Action通信实战 文章目录Action通信编写Action服务端编写Action客户端Action通信Action是ROS中最强大的一种核心通信机制是ROS2在底层利用多个 Topic 和 Service 组合封装而成专门用于长耗时、需反馈、可取消的任务。下面使用ROS2内置的Fibonacci Action 接口进行实战测试。在具体实现Topic通信的功能之前先创建工作空间具体可参考节点通信-创建工作空间。编写Action服务端在内层restaurant_robot中编写action_server.py内容如下importrclpyfromrclpy.nodeimportNodefromrclpy.actionimportActionServerfromexample_interfaces.actionimportFibonacciimporttimeclassFibonacciActionServer(Node):def__init__(self):super().__init__(fibonacci_action_server)# 创建 Action Server# 参数节点实例, Action类型, Action名称, 执行回调函数self._action_serverActionServer(self,Fibonacci,fibonacci_action,self.execute_callback)self.get_logger().info(Action Server start...)defexecute_callback(self,goal_handle):# goal_handle 包含了客户端发来的目标信息ordergoal_handle.request.order self.get_logger().info(freceived goal, calculate the first{order}items)feedback_msgFibonacci.Feedback()sequence[0,1]# 模拟长耗时任务循环计算foriinrange(1,order):# 【核心机制 1】检查客户端是否请求取消ifgoal_handle.is_cancel_requested:goal_handle.canceled()# 标记任务为已取消self.get_logger().info(goal canceled)returnFibonacci.Result()# 返回空结果# 计算下一项sequence.append(sequence[i]sequence[i-1])feedback_msg.sequencesequence# 【核心机制 2】发布实时反馈self.get_logger().info(fpublish feedback{feedback_msg.sequence})goal_handle.publish_feedback(feedback_msg)# 模拟计算耗时每秒计算一项time.sleep(1.0)# 【核心机制 3】任务完成标记为成功并返回最终结果goal_handle.succeed()resultFibonacci.Result()result.sequencesequence self.get_logger().info(任务完成返回最终结果)returnresultdefmain(argsNone):rclpy.init(argsargs)nodeFibonacciActionServer()try:rclpy.spin(node)exceptKeyboardInterrupt:passfinally:node.destroy_node()rclpy.shutdown()if__name____main__:main()退回上一级目录打开 setup.py在 console_scripts 列表中添加run_action_server restaurant_robot.action_server:main,接下来在工作空间最上层文件夹编译并运行colcon build source install/setup.bash ros2 run restaurant_robot run_action_server编写Action客户端客户端发送目标后需要注册三个回调函数处理服务端的“接受/拒绝”响应、处理“实时反馈”、处理“最终结果”。在同目录下新建文件 action_client.pyimportrclpyfromrclpy.nodeimportNodefromrclpy.actionimportActionClientfromexample_interfaces.actionimportFibonacciclassFibonacciActionClient(Node):def__init__(self):super().__init__(fibonacci_action_client)# 创建 Action Clientself._action_clientActionClient(self,Fibonacci,fibonacci_action)defsend_goal(self,order):goal_msgFibonacci.Goal()goal_msg.orderorder self.get_logger().info(wwait Action Server...)self._action_client.wait_for_server()self.get_logger().info(fsend goal: calculate the first{order}items)# 异步发送目标并绑定反馈回调函数self._send_goal_futureself._action_client.send_goal_async(goal_msg,feedback_callbackself.feedback_callback)# 当服务端返回“是否接受目标”的响应时触发 goal_response_callbackself._send_goal_future.add_done_callback(self.goal_response_callback)# 处理服务端的接受/拒绝响应defgoal_response_callback(self,future):goal_handlefuture.result()ifnotgoal_handle.accepted:self.get_logger().error(goal reffused)rclpy.shutdown()returnself.get_logger().info(goal accepted)# 异步请求最终结果绑定结果回调函数self._get_result_futuregoal_handle.get_result_async()self._get_result_future.add_done_callback(self.res_callback)# 处理实时反馈在任务执行过程中会被多次触发deffeedback_callback(self,feedback_msg):self.get_logger().info(freceived feedback:{feedback_msg.feedback.sequence})# 处理最终结果任务结束时触发一次defres_callback(self,future):resfuture.result().result self.get_logger().info(freceived result:{res.sequence})rclpy.shutdown()# 任务完成关闭节点defmain(argsNone):rclpy.init(argsargs)nodeFibonacciActionClient()# 发送目标计算前 5 项node.send_goal(5)# 保持节点运行以处理异步回调rclpy.spin(node)if__name____main__:main()同样在setup.py的console_scripyts列表中添加run_action_client restaurant_robot.action_client:main,至此在两个终端里分别运行服务端和客户端colcon build source install/setup.bash ros2 run restaurant_robot run_action_client运行结果如下[INFO][1785120497.952368565][fibonacci_action_client]:waitAction Server...[INFO][1785120498.527255191][fibonacci_action_client]: send goal: calculate the first5iterms[INFO][1785120498.530859965][fibonacci_action_client]: goal accepted[INFO][1785120498.535033490][fibonacci_action_client]: received feedback:array(i,[0,1,1])[INFO][1785120499.540644497][fibonacci_action_client]: received feedback:array(i,[0,1,1,2])[INFO][1785120500.544228609][fibonacci_action_client]: received feedback:array(i,[0,1,1,2,3])[INFO][1785120501.546219522][fibonacci_action_client]: received feedback:array(i,[0,1,1,2,3,5])[INFO][1785120502.549324776][fibonacci_action_client]: receved result: array(i,[0,1,1,2,3,5])
返回列表