一. 编写发布器节点talker
- 进入之前创建的beginner_tutorials包
//如果roscd进不了包
export ROS_PACKAGE_PATH=~/catkin_ws/src:$ROS_PACKAGE_PATH
$ roscd beginner_tutorials
- 首先创建scripts目录存放Python代码:
$ mkdir scripts
$ cd scripts
- 下载例子脚本talker.py到scripts目录,并修改权限为可执行:
$ wget https://raw.github.com/ros/ros_tutorials/kinetic-devel/rospy_tutorials/001_talker_listener/talker.py
$ chmod +x talker.py //可执行
- 浏览和编辑:
$ rosed beginner_tutorials 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
代码解释
// 每个Python的ROS节点会在顶部描述,第一行确保你的脚本是使用Python执行的脚本
#!/usr/bin/env python
# license removed for brevity
/*
*你需要导入rospy客户端库
*导入std_msgs.msg 重用std_msgs/String消息类型
**/
import rospy
from std_msgs.msg import String
def talker():
/*
*定义talker接口,pub = rospy.Publisher("chatter", String, queue_size=10)表示节点发布
*chatter话题,使用String字符类型,实际上就是类std_msgs.msg.String。queue_size表示队列的大小
*(适合hydro以后版本),如果队列消息处理不够快,就会丢弃旧的消息。
**/
pub = rospy.Publisher('chatter', String, queue_size=10)
//rospy.init_node(NAME),初始化节点,开始跟ROS master通讯。
rospy.init_node('talker', anonymous=True)
//创建Rate对象,与sleep()函数结合使用,控制话题消息的发布频率。10hz表示每秒发布10次。
rate = rospy.Rate(10) # 10hz
/*rospy.is_shutdown()返回false就会退出(例如按下Ctrl-C)
while not rospy.is_shutdown():
hello_str = "hello world %s" % rospy.get_time()
//rospy.loginfo(str)函数在屏幕输出调试信息,同时写入到节点日志文件和rosout节点
//可以通过rqt_console查看调式信息。
rospy.loginfo(hello_str)
pub.publish(hello_str)
//r.sleep()通过睡眠来,保持消息发送频率
rate.sleep()
if __name__ == '__main__':
try:
talker()
//当按下Ctrl-C或节点关闭的话,即使在rospy.sleep()和rospy.Rate.sleep()函数里都会抛出异常
except rospy.ROSInterruptException:
pass
- 您也可以传递没有参数和直接初始化字段,例如:
msg = String()
msg.data = str
- 或者你能初始化某些字段,剩余保持默认值:
String(data=str)
二.编写订阅器节点
- 下载listener.py到scripts目录
$ roscd beginner_tutorials/scripts/
$ wget https://raw.github.com/ros/ros_tutorials/kinetic-devel/rospy_tutorials/001_talker_listener/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
# node 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()
- 增加可执行权限:
$ chmod +x 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():
# 这表示节点订阅话题chatter,消息类型是 std_msgs.msgs.String
# 当接受到新消息,回调函数就触发处理这些信息,并把消息作为第一个参数传递到函数里
# ROS要求每个节点要有唯一名称,如果相同的名称,就会中止之前同名的节点。
# anonymous=True标识就会告诉rospy,要生成一个唯一的节点名称,因此你可以有多个listener.py同时运行
# 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()
三.编译节点
- 我们使用CMake作为构建系统,即使是Python节点也需要使用。
- 这确保针对消息和服务能自动生成Python代码
- 进入catkin工作空间,运行catkin_make:
$ cd ~/catkin_ws
$ catkin_make
四.测试
启动发布器
- 确保roscore可用,并运行:
$ roscore
- catkin specific 如果使用catkin,确保你在调用catkin_make后,在运行你自己的程序前,已经source了catkin工作空间下的setup.sh文件:
# In your catkin workspace
$ cd ~/catkin_ws
$ source ./devel/setup.bash
- 上个教程开发了发布节点"talker". 现在运行它:
$ rosrun beginner_tutorials talker.py (Python)
- 你将看到如下的输出信息:
[INFO] [WallTime: 1314931831.774057] hello world 1314931831.77
[INFO] [WallTime: 1314931832.775497] hello world 1314931832.77
[INFO] [WallTime: 1314931833.778937] hello world 1314931833.78
[INFO] [WallTime: 1314931834.782059] hello world 1314931834.78
[INFO] [WallTime: 1314931835.784853] hello world 1314931835.78
[INFO] [WallTime: 1314931836.788106] hello world 1314931836.79
- 发布器节点已经启动运行。现在需要一个订阅器节点来接受发布的消息。
启动订阅器
- 上一教程,我们编写了一个名为"listener"的订阅器节点。现在运行它:
$ rosrun beginner_tutorials listener.py (Python)
你将会看到如下的输出信息:
[INFO] [WallTime: 1314931969.258941] /listener_17657_1314931968795I heard hello world 1314931969.26
[INFO] [WallTime: 1314931970.262246] /listener_17657_1314931968795I heard hello world 1314931970.26
[INFO] [WallTime: 1314931971.266348] /listener_17657_1314931968795I heard hello world 1314931971.26
[INFO] [WallTime: 1314931972.270429] /listener_17657_1314931968795I heard hello world 1314931972.27
[INFO] [WallTime: 1314931973.274382] /listener_17657_1314931968795I heard hello world 1314931973.27
[INFO] [WallTime: 1314931974.277694] /listener_17657_1314931968795I heard hello world 1314931974.28
[INFO] [WallTime: 1314931975.283708] /listener_17657_1314931968795I heard hello world 1314931975.28