学习参考:赵虚左的课程、古月的ROS机器人开发实践、约瑟夫的精通ROS机器人编程
一、增
创建scripts文件夹,创建demo01_param_set_p.py
demo01_param_set_p.py
#! /usr/bin/env python
# -*- coding: UTF-8 -*-
import rospy
if __name__ == "__main__":
rospy.init_node("param_set_p")
rospy.set_param("zhonglei","huang")
rospy.set_param("banjing",0.20)
rospy.loginfo("参数添加成功")
对比c++,不在需要句柄,同时程序非常简洁。
rospy.set_param("zhonglei","huang")
通过句点表示法调用rospy下的set_param函数,第一个参数为键名,第二个参数为键值。
给scripts文件夹内python文件添加可执行权限
chmod +x *.py
CMakeList.txt配置
catkin_install_python(PROGRAMS
scripts/demo01_param_set_p.py
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
启动ROS Master,运行代码
roscore
rosrun parameter_server demo01_param_set_p.py
检查参数服务器参数添加情况
rosparam list
ros参数服务器参数列出。
查询键名所对应的键值
rosparam get 键名
rosparam get banjing
二、改
#! /usr/bin/env python
# -*- coding: UTF-8 -*-
import rospy
if __name__ == "__main__":
rospy.init_node("param_set_p")
rospy.set_param("zhonglei","huang")
rospy.set_param("banjing",0.20)
rospy.set_param("banjing",0.88)
rospy.loginfo("参数添加成功")
通过覆盖的形式进行修改。
rosrun parameter_server demo01_param_set_p.py
rosparam get banjing
三、读
创建demo01_param_get_p.py,其中添加可执行权限与配置CMakeList.txt与之前流程相同。
1.第一种方法get_param
#! /usr/bin/env python
# -*- coding: UTF-8 -*-
import rospy
if __name__ == "__main__":
rospy.init_node("get_param_p")
banjing1 = rospy.get_param("banjing",0.30)
banjing2 = rospy.get_param("banjing_1",0.40)
rospy.loginfo("banjing:%.2f",banjing1)
rospy.loginfo("banjing_1:%.2f",banjing2)
其中读取利用get_param函数,第一个参数为读取键名,第二个参数是没找到键名时给的默认值。
banjing是之前添加的参数服务器参数,所以能读取到键值,banjing_1为不存在的键名,故其键值由于get_param函数的第二个参数,取默认值0.40。
2.第二种方法 get_param_cached
从缓存查询,当键已经被查询过,这个函数可以直接从缓存查询,提高效率。
#! /usr/bin/env python
# -*- coding: UTF-8 -*-
import rospy
if __name__ == "__main__":
rospy.init_node("get_param_p")
banjing1 = rospy.get_param("banjing",0.30)
banjing2 = rospy.get_param("banjing_1",0.40)
rospy.loginfo("banjing:%.2f",banjing1)
rospy.loginfo("banjing_1:%.2f",banjing2)
banjing3 = rospy.get_param_cached("banjing",0.30)
banjing4 = rospy.get_param_cached("banjing_1",0.40)
rospy.loginfo("banjing:%.2f",banjing3)
rospy.loginfo("banjing_1:%.2f",banjing4)
其函数使用与第一种方法相同。结果也相同。
3.第三种方法get_param_name
#! /usr/bin/env python
# -*- coding: UTF-8 -*-
import rospy
if __name__ == "__main__":
rospy.init_node("get_param_p")
banjing1 = rospy.get_param("banjing",0.30)
banjing2 = rospy.get_param("banjing_1",0.40)
rospy.loginfo("banjing:%.2f",banjing1)
rospy.loginfo("banjing_1:%.2f",banjing2)
banjing3 = rospy.get_param_cached("banjing",0.30)
banjing4 = rospy.get_param_cached("banjing_1",0.40)
rospy.loginfo("banjing:%.2f",banjing3)
rospy.loginfo("banjing_1:%.2f",banjing4)
names = rospy.get_param_names()
for name in names:
rospy.loginfo("name = %s",name)
关键部分
names = rospy.get_param_names()
for name in names:
rospy.loginfo("name = %s",name)
读取所有的键名,并存入一个列表,其中这个案例充分证明了python的优越性。如下是c++实现,代码可读性对比显然易见。
ros::NodeHandle n;
std::vector<std::string> names;
n.getParamNames(names);
for (auto &&name : names)
{
ROS_INFO("遍历到的元素:%s",name.c_str());
}
结果:
4.第4种方法has_param
#! /usr/bin/env python
# -*- coding: UTF-8 -*-
import rospy
if __name__ == "__main__":
rospy.init_node("get_param_p")
banjing1 = rospy.get_param("banjing",0.30)
banjing2 = rospy.get_param("banjing_1",0.40)
rospy.loginfo("banjing:%.2f",banjing1)
rospy.loginfo("banjing_1:%.2f",banjing2)
banjing3 = rospy.get_param_cached("banjing",0.30)
banjing4 = rospy.get_param_cached("banjing_1",0.40)
rospy.loginfo("banjing:%.2f",banjing3)
rospy.loginfo("banjing_1:%.2f",banjing4)
names = rospy.get_param_names()
for name in names:
rospy.loginfo("name = %s",name)
flag1 = rospy.has_param("banjing")
flag2 = rospy.has_param("banjing_1")
if flag1:
rospy.loginfo("banjing存在")
else:
rospy.loginfo("banjing不存在")
if flag2:
rospy.loginfo("banjing_1存在")
else:
rospy.loginfo("banjing_1不存在")
关键部分
flag1 = rospy.has_param("banjing")
flag2 = rospy.has_param("banjing_1")
if flag1:
rospy.loginfo("banjing存在")
else:
rospy.loginfo("banjing不存在")
if flag2:
rospy.loginfo("banjing_1存在")
else:
rospy.loginfo("banjing_1不存在")
has_param参数为键名,返回值为代表着查询成功与否的布尔类型。
结果:
符合预期。
5.第5种方法search_param
#! /usr/bin/env python
# -*- coding: UTF-8 -*-
import rospy
if __name__ == "__main__":
rospy.init_node("get_param_p")
banjing1 = rospy.get_param("banjing",0.30)
banjing2 = rospy.get_param("banjing_1",0.40)
rospy.loginfo("banjing:%.2f",banjing1)
rospy.loginfo("banjing_1:%.2f",banjing2)
banjing3 = rospy.get_param_cached("banjing",0.30)
banjing4 = rospy.get_param_cached("banjing_1",0.40)
rospy.loginfo("banjing:%.2f",banjing3)
rospy.loginfo("banjing_1:%.2f",banjing4)
names = rospy.get_param_names()
for name in names:
rospy.loginfo("name = %s",name)
flag1 = rospy.has_param("banjing")
flag2 = rospy.has_param("banjing_1")
if flag1:
rospy.loginfo("banjing存在")
else:
rospy.loginfo("banjing不存在")
if flag2:
rospy.loginfo("banjing_1存在")
else:
rospy.loginfo("banjing_1不存在")
key1 = rospy.search_param("banjing")
key2 = rospy.search_param("banjing_1")
rospy.loginfo("查询到key1为%s",key1)
rospy.loginfo("查询到key2为%s",key2)
关键部分
key1 = rospy.search_param("banjing")
key2 = rospy.search_param("banjing_1")
rospy.loginfo("查询到key1为%s",key1)
rospy.loginfo("查询到key2为%s",key2)
search_param函数返回值为查询的键名,存在时返回键名,不存在时返回None。
结果:
四、删
创建demo01_param_del_p.py,其中添加可执行权限,CMakeList.txt与之前流程相同。
相较于c++的实现,如果没学过python的异常操作,c++实现更容易。
demo01_param_del_p.py
#! /usr/bin/env python
# -*- coding: UTF-8 -*-
import rospy
if __name__ == "__main__":
rospy.init_node("del_param_p")
rospy.delete_param("banjing")
rospy.loginfo("删除成功")
try:
rospy.delete_param("banjing")
except Exception as e:
rospy.loginfo("被删除的参数不存在")
第一次删除成功删除,第二次删除由于键已经被删除,找不到键,故采用异常操作,目的是报错了程序仍能继续进行。
结果:
将刚刚的zhonglei键也删除掉
#! /usr/bin/env python
# -*- coding: UTF-8 -*-
import rospy
if __name__ == "__main__":
rospy.init_node("del_param_p")
# rospy.delete_param("banjing")
# rospy.loginfo("删除成功")
try:
rospy.delete_param("banjing")
except Exception as e:
rospy.loginfo("被删除的参数不存在")
try:
rospy.delete_param("zhonglei")
except Exception as e:
rospy.loginfo("被删除的参数不存在")
结果:banjing刚刚已经被删了,报出异常。zhonglei没有被删,为存在状态了,没有报异常。
查询参数服务器参数
rosparam list
只剩下系统自带的参数了。