ROS学习笔记14:Action通信

前言

本人ROS小白,利用寒假时间学习ROS,在此以笔记的方式记录自己每天的学习过程。争取写满20篇(14/20)。
环境:Ubuntu20.04、ROS1:noetic
环境配置:严格按照下方学习链接的教程配置,基本一次成功。
学习链接:【Autolabor初级教程】ROS机器人入门
对应链接文档:ROS机器人入门课程《ROS理论与实践》
笔记绝大部分代码使用Python语言编写。
本期关键词:action通信,action文件,代码实现

action通信

action通信是一种类似服务通信的实现。
服务通信回顾:ROS中的服务通信是一种基于请求-响应模式的通信机制。它允许一个节点(客户端)向另一个节点(服务器)发送一个请求,并期望得到一个响应。
action通信的不同之处在于,在请求和响应的过程中,服务端还可以连续的反馈当前任务进度,客户端可以接收连续反馈并且还可以取消任务。

action文件

  1. 使用action通信之前,需要自定义action文件。
  2. 创建流程主要有以下:
    • 创建功能包,导入roscpp rospy std_msgs actionlib actionlib_msgs依赖
    • 创建action目录,新增XXX.action文件
    • 编写action文件
    • 编辑CMakeLists.txt,编译
  3. action文件编写示例:
#目标值
int32 num
---
#最终结果
int32 result
---
#连续反馈
float64 progress_bar
  1. 配置CMakeLists.txt
find_package
(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  actionlib
  actionlib_msgs
)
add_action_files(
  FILES
  AddInts.action
)
generate_messages(
  DEPENDENCIES
  std_msgs
  actionlib_msgs
)
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES demo04_action
 CATKIN_DEPENDS roscpp rospy std_msgs actionlib actionlib_msgs
#  DEPENDS system_lib
)
  1. 配置好以上文件后,编译一下功能包,如果能在工作空间的./devel/lib/python3/dist-packages/功能包名/msg路径下找到相应的.py文件,就说明配置成功了。

代码实现

写代码前配置一下vscode的settings.json文件:

{
    "python.autoComplete.extraPaths": [
        "/opt/ros/noetic/lib/python3/dist-packages",
        "/home/用户名/工作空间/devel/lib/python3/dist-packages"
    ],
    "python.analysis.extraPaths": [
        "/opt/ros/noetic/lib/python3/dist-packages",
        "/home/用户名/工作空间/devel/lib/python3/dist-packages"
    ]
}

服务端实现

  1. 示例代码如下:
#! /usr/bin/env python

import rospy
import actionlib
from action_demo.msg import *

class MyactionServer:
    def __init__(self):
        self.server=actionlib.SimpleActionServer("addInts",addIntsAction,self.cb,False) # 初始化actionserver
        self.server.start()# 手动启动
        rospy.loginfo("启动服务端")
        
    def cb(self,goal):
        rospy.loginfo("服务端接收数据并处理...")
        num=goal.num # 目标值
        rate=rospy.Rate(10) # 频率设置
        sum=0
        for i in range(1,num+1):
            sum=sum+i
            feedBack=i/num
            rospy.loginfo("当前进度为:%.2f",feedBack)
            feedBack_obj=addIntsFeedback() # 创建反馈对象
            feedBack_obj.progress_bar=feedBack # 更新进度反馈
            self.server.publish_feedback(feedBack_obj) # 发布反馈
            rate.sleep()
        result=addIntsResult() # 创建结果对象
        result.result=sum
        self.server.set_succeeded(result) # 设置结果
        rospy.loginfo("响应结果:%d",sum)

if __name__ == "__main__":
    rospy.init_node("action_server")
    server=MyactionServer()
    rospy.spin()
  1. 运行roscore,运行上述py文件,然后用以下指令测试:
rostopic pub /addInts/goal action_demo/addIntsActionGoal "header:
  seq: 0
  stamp:
    secs: 0
    nsecs: 0
  frame_id: ''
goal_id:
  stamp:
    secs: 0
    nsecs: 0
  id: ''
goal:
  num: 10"
  1. 测试结果(服务端输出)为:
[INFO] [1707276109.150858]: 启动服务端
[INFO] [1707276109.154917]: 服务端接收数据并处理...
[INFO] [1707276109.156253]: 当前进度为:0.10
[INFO] [1707276109.256684]: 当前进度为:0.20
[INFO] [1707276109.357126]: 当前进度为:0.30
[INFO] [1707276109.456856]: 当前进度为:0.40
[INFO] [1707276109.556789]: 当前进度为:0.50
[INFO] [1707276109.656637]: 当前进度为:0.60
[INFO] [1707276109.757014]: 当前进度为:0.70
[INFO] [1707276109.857132]: 当前进度为:0.80
[INFO] [1707276109.956711]: 当前进度为:0.90
[INFO] [1707276110.056985]: 当前进度为:1.00
[INFO] [1707276110.156786]: 响应结果:55

客户端实现

  1. 示例代码如下:
#! /usr/bin/env python
import rospy
import actionlib
from action_demo.msg import *

def done_cb(state,result): # 最终响应结果
    if state==actionlib.GoalStatus.SUCCEEDED:
        rospy.loginfo("响应结果:%d",result.result)

def active_cb():
    rospy.loginfo("服务被激活....")
    
def fb_cb(fb): # 连续反馈
    rospy.loginfo("当前进度:%.2f",fb.progress_bar)


if __name__ == "__main__":
    rospy.init_node("action_client")
    client = actionlib.SimpleActionClient("addInts",addIntsAction) # 创建action Client对象
    client.wait_for_server()
    goal_obj = addIntsGoal() # 创建目标对象
    goal_obj.num=10
    client.send_goal(goal_obj,done_cb,active_cb,fb_cb) # 三个回调函数:最终结果回调,服务激活回调,连续反馈回调
    
    rospy.spin()
  1. 客户端测试结果如下:
[INFO] [1707277093.197503]: 服务被激活....
[INFO] [1707277093.202111]: 当前进度:0.10
[INFO] [1707277093.302037]: 当前进度:0.20
[INFO] [1707277093.401460]: 当前进度:0.30
[INFO] [1707277093.501693]: 当前进度:0.40
[INFO] [1707277093.601486]: 当前进度:0.50
[INFO] [1707277093.701373]: 当前进度:0.60
[INFO] [1707277093.801347]: 当前进度:0.70
[INFO] [1707277093.901595]: 当前进度:0.80
[INFO] [1707277094.000832]: 当前进度:0.90
[INFO] [1707277094.101861]: 当前进度:1.00
[INFO] [1707277094.200175]: 响应结果:55

往期内容

  1. ROS学习笔记1:基础知识
  2. ROS学习笔记2:话题通信
  3. ROS学习笔记3:服务通信与参数服务器
  4. ROS常用命令记录
  5. ROS学习笔记4:通信机制实操
  6. ROS学习笔记5:常用API和模块导入
  7. ROS学习笔记6:launch文件
  8. ROS学习笔记7:重名解决与名称设置
  9. ROS学习笔记8:TF坐标变换
  10. ROS学习笔记9:TF坐标变换实操
  11. ROS学习笔记10:rosbag与rqt
  12. ROS学习笔记11:URDF
  13. ROS学习笔记12:机器人导航实现(理论)
  14. ROS学习笔记13:导航相关消息

你可能感兴趣的:(学习,笔记,python,c++,vscode)