本人ROS小白,利用寒假时间学习ROS,在此以笔记的方式记录自己每天的学习过程。争取写满20篇(14/20)。
环境:Ubuntu20.04、ROS1:noetic
环境配置:严格按照下方学习链接的教程配置,基本一次成功。
学习链接:【Autolabor初级教程】ROS机器人入门
对应链接文档:ROS机器人入门课程《ROS理论与实践》
笔记绝大部分代码使用Python语言编写。
本期关键词:action通信,action文件,代码实现
action通信是一种类似服务通信的实现。
服务通信回顾:ROS中的服务通信是一种基于请求-响应模式的通信机制。它允许一个节点(客户端)向另一个节点(服务器)发送一个请求,并期望得到一个响应。
action通信的不同之处在于,在请求和响应的过程中,服务端还可以连续的反馈当前任务进度,客户端可以接收连续反馈并且还可以取消任务。
roscpp rospy std_msgs actionlib actionlib_msgs
依赖#目标值
int32 num
---
#最终结果
int32 result
---
#连续反馈
float64 progress_bar
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
)
./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"
]
}
#! /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()
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"
[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
#! /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()
[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