如何在ros上编写一个简单的node并进行通信。
这里采用ros教程的例子,稍作修改。
与C++不同的是,python不需要在package中加入message_runtime以及message_generation.
我自己的package文件如下:
.......
.......
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<build_depend>rospy</build_depend>
<build_depend>std_msgs</build_depend>
<build_depend>message_generation</build_depend>
<build_export_depend>roscpp</build_export_depend>
<build_export_depend>rospy</build_export_depend>
<build_export_depend>std_msgs</build_export_depend>
<exec_depend>roscpp</exec_depend>
<exec_depend>rospy</exec_depend>
<exec_depend>std_msgs</exec_depend>
<exec_depend>message_runtime</exec_depend>
........
........
对CMakeLists.txt也不需要作什么更改。
之后就可以开始放你的pyton文件了,当然,你也可以先吧python文件方好,放在包的scripts文件夹中(需要自己新建)。
这里假设你发布信息的python文件叫talker.py,且代码如下:
#!/usr/bin/env python
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
这里,对每一行的代码进行解析:
1.
#!/usr/bin/env python
每个python ros节点的顶部都将有此声明,第一行确保脚本作为python叫脚本执行。
2.
import rospy
from std_msgs.msg import String
rospy是每个ros node必须要的,std_msg.msg import String则声明需要用到String类型,其他的std_msgs包内的msg文件夹中的类型也都可以根据需要而调用。(这里,String是用来发布信息的)
3.
pub = rospy.Publisher('chatter',String,queue_size = 10)
rospy.init_node('talker',anonymous = True)
这部分定义了talker与tos其他部分的接口
pub = rospy.Publisher("chatter",String,queue_size = 10)表示:该结点向 /chatter 主题发布String类型的信息。queue_size=10表示如果如何的订阅者接受信息的速度不够快,则限制排队的信息。
rospy.init_node('talker',anonymous=True)则是告诉rospy你的结点名为talker。那边的什么什么=true则使得可以有多个结点同时命名为talker,因为该语句最后会给你的结点命名为talker+(随机数)。rospy只有得到该信息后,才能实现与master的通信。
注意:这里的名字不可以有斜杠"/"。
4.
rate = rospy.Rate(10) #10Hz
5.
while not rospy.is_shutdown():
hello_str = "hello world %s" % rospy.get_time()
rospy.loginfo(hello_str)
pub.publish(hello_str)
rate.sleep()
循环是一个相当标准的rospy构造:rospy.is_shutdown()检查rospy是否还在运行,运行状态下,pub.publish会发布一个字符串给主题"chatter".循环时还调用rate.sleep()睡眠足够长的时间,以便通过循环保持所需的速率。
rospy.loginfo(str) 则打印消息到屏幕、结点的日志文件、rosout。
6.
try:
talker()
except rospy.ROSInterruptException:
pass
除了标准的python __main__检查外,这亥捕获了一个rospy。
rospy.ROSInterruptException异常可以由rospy.sleep()和rospy.Rate.sleep()方法引发。
你的接受信息的文件叫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():
rospy.init_node('listener', anonymous=True)
rospy.Subscriber('chatter', String, callback)
rospy.spin()
if __name__ == '__main__':
listener()
1.
这里的from std_msgs.msg import String声明了你的结点接受的类型为String
2.
rospy.init_node('listener',anonymous = True) 说明该结点明为listener,anonymous跟上面讲到的一样。
3.
rospy.spin()则是让你的结点持续运行,知道结点被杀为止。与roscpp不同的是,rospy.spin()不会影响订阅者的回调函数,因为这些函数有自己的线程。
回归正题:
之后,把python文件变为可执行文件,使用指令:
$ chmod +x taliker.py
$ chmod +x listener.py
然后你就可以建立自己的节点拉,使用指令:
$ cd ~/catkin_ws
$ catkin_make
然后就可以用
$ roscore
$ rosrun [包名] [节点名]
运行你编写的节点。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)