有时候想想,国内有些资源确实比较稀缺,但是我们一样不会落后!学习python和ROS这么久了,一直很少去实战,另外看到基于python编程的ROS话题通信教程实在是稀缺了,或者对小白不是那么的友好,所以写下这篇教程与你一起进步。
关于ROS很基本的知识,比如:怎么启动roscore;怎么创建工作空间;source环境;python脚本的执行权限等我就不讲解了。主要是代码部分讲解!
把下面的内容:
source /home/xiaolong/ros_practice/devel/setup.bash
放在.bashrc末尾,这个不懂得看我之前的博客
传送门: https://blog.csdn.net/qq_45152498/article/details/108652439
在scripts下创建talker.py
并确保它有可执行权限。
让我先把整体代码给你,让你有一个整体的印象:
#!/usr/bin/env python
# license removed for brevity
import rospy
from std_msgs.msg import String
def talker():
pub = rospy.Publisher('chatter', String, queue_size=10)
rospy.init_node('talker', anonymous=True)
rate = rospy.Rate(10) # 10hz
while not rospy.is_shutdown():
hello_str = "hello world %s" % rospy.get_time()
rospy.loginfo(hello_str)
pub.publish(hello_str)
rate.sleep()
if __name__ == '__main__':
try:
talker()
except rospy.ROSInterruptException:
pass
然后开始一点点分析:
#!/usr/bin/env python
import rospy
from std_msgs.msg import String
pub = rospy.Publisher('chatter', String, queue_size=10)
rospy.init_node('talker', anonymous=True)
rate = rospy.Rate(10)
while not rospy.is_shutdown():
hello_str = "hello world %s" % rospy.get_time()
rospy.loginfo(hello_str)
pub.publish(hello_str)
rate.sleep()
rospy.loginfo(hello_str)
pub.publish(hello_str)
rate.sleep()
try:
talker()
except rospy.ROSInterruptException:
pass
总结:如何实现一个发布者?
• 初始化ROS节点;
• 向ROS Master注册节点信息,包括发布的话题名和话题中的消息类型;
• 创建消息数据;
• 按照一定频率循环发布消息。
在scripts下创建listener.py
并确保它有可执行权限。
#!/usr/bin/env python
import rospy
from std_msgs.msg import String
def callback(data):
rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.data)
def listener():
# In ROS, nodes are uniquely named. If two nodes with the same
# name are launched, the previous one is kicked off. The
# anonymous=True flag means that rospy will choose a unique
# name for our 'listener' node so that multiple listeners can
# run simultaneously.
rospy.init_node('listener', anonymous=True)
rospy.Subscriber("chatter", String, callback)
# spin() simply keeps python from exiting until this node is stopped
rospy.spin()
if __name__ == '__main__':
listener()
这个和talker.py
类似,除了我们已经引入了一种新的基于回调的机制来订阅消息。
rospy.Subscriber("chatter", String, callback)
rospy.spin()
总结:如何实现一个订阅者?
• 初始化ROS节点;
• 订阅需要的话题;
• 循环等待话题消息,接收到消息后进入回调函数;
• 在回调函数中完成消息处理。
1.让我们看看src:
2.启动ROS Master:
roscore
3.启动发布者和订阅者:
1.在运行节点后可以关闭roscore,此时也可以正常发布和接收。但是不启动ROS Master直接运行程序却不行。
2.python脚本可以不用编译直接执行,相当于你不用修改CMakeLists.txt文件。但是编译运行需要添加东西。官方Wiki是说:
但是在工作空间catkin_make却不能通过,而下面这样可以:
3.scripts文件夹可以不要,直接放在topic功能包下,这是因为我们的程序以及功能简单,但是我还是希望你放在scripts下,因为以后你的功能包下基本不会只有python脚本,而没有其它文件。
4.可以用下面两行代替上面一行,这样执行效果一样:
def callback(data):
rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.data)
这说明传递过来的是String对象,而消息内容的话当然是String.data(即data.data)。
注意:String是不能直接更改的,因为这是ROS内部封装好的,你只能引用,要是直接更改岂不是乱套了嘛。就像上面的hello_str = String(),然后hello_str = “hello world %s” % rospy.get_time()
而使用String.data替代hello_str.data是错误的。
注:以上完全是自己摸索出来的,小白看不懂没有关系,还有大家摸索出来其他东西或者和我的类似,或者知道这其中原理的,欢迎交流哟!
1.基本概念:
2.话题通信机制:
本文内容参考:
ROS官方wiki:http://wiki.ros.org
古月——ROS入门21讲
《ROS机器人开发实践》
如有错误或者不足之处,欢迎大家留言指正!