目录
学习参考:B站赵虚左的ROS教程
一.以话题通信的python初始化节点api进阶使用
1.初始化节点代码提示与python话题通信例程
def init_node(name, argv=None, anonymous=False, log_level=None, disable_rostime=False,disable_rosout=False, disable_signals=False, xmlrpc_port=0, tcpros_port=0):
利用到之前学习的话题通信python实现
2.初始化节点使用进阶
作用:ROS初始化
参数:name ---- 设置节点名称,必须保证节点名称唯一,argv=None ---- 封装节点调用时传递的参数,anonymous=False ---- 可以为节点生成随机数后缀,可以解决相同节点启动两次节点重名导致前一节点shotdown问题.
使用:
1.argv使用
可以按照ROS中指定的语法格式传参,ROS可以解析并加以使用.
在启动节点时,添加了 _A:=1000,作用是在参数服务器添加键名A,同时键值为1000
rosmelodic@rosmelodic-virtual-machine:~/catkin_ws$ rosrun sub_pub pub_p.py _A:=1000
参考参数服务器python实现:
列出参数服务器的所有参数。
rosparam list
可知键名为/pub_py/A
rosmelodic@rosmelodic-virtual-machine:~/catkin_ws$ rosparam list
/pub_py/A
/rosdistro
/roslaunch/uris/host_rosmelodic_virtual_machine__41671
/rosversion
/run_id
查找指定键名的键值
rosparam get /pub_py/A
键值为1000
rosmelodic@rosmelodic-virtual-machine:~/catkin_ws$ rosparam get /pub_py/A
1000
由此可见在启动节点时,加入符合特定语法的代码,ROS能解析,并实现功能,这是因为传入参数被初始化节点的argv形参(是一个列表)接收,实现了功能。如下是初始化函数封装的一部分代码,可见argv传入的就是系统的argv,如果相对argv操作,import sys。
if argv is None:
argv = sys.argv
同样的argv也在服务通信的客户端优化中应用了
(4条消息) 8.ROS编程学习:自定义服务数据python调用_机械专业的计算机小白的博客-CSDN博客https://blog.csdn.net/wzfafabga/article/details/1273960592.anonymous使用
如果同时启动两次
rosmelodic@rosmelodic-virtual-machine:~/catkin_ws$ rosrun sub_pub pub_p.py
第一个启动的节点的终端会提示:
shutdown request: [/pub_py] Reason: new node registered with same name
修改初始化节点:
pub_p.py
#! /usr/bin/env python
# -*- coding: UTF-8 -*-
import rospy
from std_msgs.msg import String
if __name__ == "__main__":
rospy.init_node(name = "pub_py", anonymous = True)
pub = rospy.Publisher (name="chongfu_py", data_class = String, queue_size=10)
msg = String()
rate = rospy.Rate(1)
count = 0
rospy.sleep(3)
while not rospy.is_shutdown():
count += 1
if(count <= 10):
msg.data = "hello" + str(count)
pub.publish(msg)
rospy.loginfo("发布数据:%s", msg.data)
else:
rospy.signal_shutdown("退出循环")
rate.sleep()
从
rospy.init_node(name = "pub_py")
修改为
rospy.init_node(name = "pub_py", anonymous = True)
同时启动两次节点。
rosrun sub_pub pub_p.py
rosrun sub_pub pub_p.py
查看所有启动节点。
rosnode list
节点后跟有随机数,使相同节点启动节点名不同,不会造成第一个启动的节点被shotdown。
rosmelodic@rosmelodic-virtual-machine:~/catkin_ws$ rosnode list
/pub_py_20907_1667219173751
/pub_py_20951_1667219175884
/rosout
二、话题通信发布方对象进阶
作用与c++对应,主要还是处理latch的布尔值。
官方解释:@param latch:如果为True,则最后发布的消息是“latch”,这意味着任何未来的订阅者将在连接后立即收到该消息。
@param latch: If True, the last message published is 'latched', meaning that any future subscribers will be sent that message immediately upon connection.
pub_p.py
#! /usr/bin/env python
# -*- coding: UTF-8 -*-
import rospy
from std_msgs.msg import String
if __name__ == "__main__":
rospy.init_node(name = "pub_py", anonymous = True)
pub = rospy.Publisher(name="chongfu_py", data_class = String, queue_size= 10, latch = True)
msg = String()
rate = rospy.Rate(1)
count = 0
rospy.sleep(3)
while not rospy.is_shutdown():
count += 1
if(count <= 10):
msg.data = "hello" + str(count)
pub.publish(msg)
rospy.loginfo("发布数据:%s", msg.data)
# else:
# rospy.signal_shutdown("退出循环")
rate.sleep()
修改:
发布者的创建修改前:
pub = rospy.Publisher(name="chongfu_py", data_class = String, queue_size= 10)
发布者的创建修改后:
pub = rospy.Publisher(name="chongfu_py", data_class = String, queue_size= 10, latch = True)
测试:
启动发布者
rosrun sub_pub pub_p.py
循环到十次时停止发布消息,如果latch为False,订阅者这时启动是不会接收到任何消息的。
rosmelodic@rosmelodic-virtual-machine:~/catkin_ws$ rosrun sub_pub pub_p.py
[INFO] [1667221214.189930]: 发布数据:hello1
[INFO] [1667221214.191267]: 发布数据:hello2
[INFO] [1667221215.193347]: 发布数据:hello3
[INFO] [1667221216.192330]: 发布数据:hello4
[INFO] [1667221217.192395]: 发布数据:hello5
[INFO] [1667221218.192578]: 发布数据:hello6
[INFO] [1667221219.193270]: 发布数据:hello7
[INFO] [1667221220.192703]: 发布数据:hello8
[INFO] [1667221221.193090]: 发布数据:hello9
[INFO] [1667221222.192738]: 发布数据:hello10
由于本程序latch为True,订阅者接收到了最后发布的一条消息,其中原理与c++实现相同,只不过ROS提供了python接口。
rosmelodic@rosmelodic-virtual-machine:~/catkin_ws$ rosrun sub_pub sub_p.py
[INFO] [1667221300.839786]: 订阅的数据:hello10
三、回头函数
python中只有不停的回头spin,没有回一次头的函数spinonce。
rospy.spin()
与c++相同,运行到回头函数就会在回调函数中不停的循环,回头函数后面的代码不会运行。