前言
本人ROS小白,利用寒假时间学习ROS,在此以笔记的方式记录自己每天的学习过程。争取写满15篇(3/15)。
环境:Ubuntu20.04、ROS1:noetic
环境配置:严格按照下方学习链接的教程配置,基本一次成功。
学习链接:【Autolabor初级教程】ROS机器人入门
对应链接文档:ROS机器人入门课程《ROS理论与实践》
笔记绝大部分代码使用Python语言编写。
本期关键词:请求响应,srv,参数服务器,增改查删
服务通信
理论模型:
- ROS Master(管理者)
- Server(服务端)
- Client(客户端)
1. 自定义srv
- 流程与msg类似:按照固定格式创建srv文件;编辑配置文件;编译生成中间文件。
- 在ROS功能包下新建srv目录,创建
AddInts.srv
文件,数据用---
分隔,之上是请求,之下是响应。
int32 num1
int32 num2
---
int32 sum
2. 服务端实现
- 代码如下:
#! usr/bin/env python
import rospy
# from helloworld.srv import AddInts,AddIntsRequest,AddIntsResponse
from helloworld.srv import *
def doSum(req):
sum = req.num1+req.num2
rospy.loginfo("get data: %d and %d, return %d",req.num1,req.num2,sum)
resp=AddIntsResponse(sum)
return resp
if __name__=="__main__":
rospy.init_node("server_p")
rospy.loginfo("Service Start!")
server = rospy.Service("Adds",AddInts,doSum)
rospy.spin()
- 运行服务端代码后,可以使用以下指令测试服务端。指令中的“Adds”对应话题名称,我这里是“Adds“。如果名称没有错,其他步骤也没有错的话,按下
Tab
键可以自动补齐后面的num1、num2,然后填入测试数据。
rosservice call Adds "num1: 10
num2: 20"
3. 客户端实现
- 代码如下:
#! /usr/bin/env python
import rospy
from helloworld.srv import *
import sys
if __name__=="__main__":
if len(sys.argv)!=3:
# 传入三个参数,第一个参数是文件名,是默认的,后两个才是自定义参数
# 注意下面是logerr不是loginfo
rospy.logerr("Please enter right data!")
sys.exit(1)
rospy.init_node("client_p")
client=rospy.ServiceProxy("Adds",AddInts)
client.wait_for_service()
# rospy.wait_for_service("Adds")# 另一种等待服务器的方式
req=AddIntsRequest()
req.num1=int(sys.argv[1])
req.num2=int(sys.argv[2])
resq=client.call(req)
rospy.loginfo("the result is: %d",resq.sum)
- 该代码在运行终端rosrun指令时,需要输入num1和num2参数的数值,否者会有报错提示。示例:
rosrun helloworld demo_client.py 10 20
参数服务器
理论模型:
- ROS Master(管理者)
- Talker(参数设置者)
- Listener(参数调用者)
可用数据类型:
- 32-bit integers
- booleans
- strings
- doubles
- iso8601 dates(时间类型)
- lists
- base64-encoded binary data(一般不用)
- 字典
增改查删
- “增改”对应方法:
set_param
#! usr/bin/env python
import rospy
if __name__=="__main__":
rospy.init_node("param_set")
rospy.set_param("robot_name","Ming")# 增
rospy.set_param("height",1.77)# 增
rospy.set_param("height",1.80)# 改
- “查”对应方法:
get_param
、get_param_cached
、get_param_names
、has_param
、search_param
#! usr/bin/env python
import rospy
if __name__=="__main__":
rospy.init_node("param_search")
h_value=rospy.get_param("height")# get_param_cached结果与其相同
rospy.loginfo("I get %.2f",h_value)
rospy.loginfo("weight's state: %s",rospy.has_param("weight"))#返回False
names=rospy.get_param_names()
for name in names:
rospy.loginfo("name = %s",name)
rospy.loginfo("What I search is %s",rospy.search_param("height"))#返回/height
- “删”对应方法:
delete_param
#! usr/bin/env python
import rospy
if __name__=="__main__":
rospy.init_node("param_del")
try:
rospy.delete_param("weight")
except Exception as e:
rospy.loginfo("delete false!")
rospy.logerr(e)# ouput error
以上代码编写运用到了“try 块“,用于尝试执行可能会引发异常的代码。如果代码块中的操作成功执行,那么不会有异常发生,程序将继续执行。如果发生异常,程序将跳转到 except
块。
except Exception as e:
:这是一个异常处理块。如果 try
块中的代码引发了异常,程序将执行这里的代码。Exception
是Python中的一个基类,用于捕获所有类型的异常。as e
表示将捕获到的异常对象赋值给变量 e
。
以上代码中,运行rospy.logerr(e)
将异常对象输出。
4. “增改查删”除了上述的方法外,也可以通过终端命令对参数服务器的值进行操作,列举部分指令如下:
rosparam set set parameter
rosparam get get parameter
rosparam load load parameters from file
rosparam dump dump parameters to file
rosparam delete delete parameter
rosparam list list parameter names