欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ROS与Python入门教程-写简单发布器和订阅器(2)

程序员文章站 2022-06-04 15:45:22
...

ROS与Python入门教程-写简单发布器和订阅器

说明:

  • 这一节介绍定义msg消息,创建两个简单的rospy节点。
  • "talker"节点发布信息在主题"chatter","listener"节点接受和打印信息。

定义msg消息

  1. 在beginner_tutorials,新建msg消息目录,新建Num.msg文件
$ roscd beginner_tutorials
$ mkdir msg
$ cd msg
$ touch Num.msg
$ rosed beginner_tutorials Num.msg
  1. Num.msg文件,手工输入代码:
int64 num
  1. 打开文件rosed beginner_tutorials package.xml,增加依赖,
<build_depend>message_generation</build_depend>
<run_depend>message_runtime</run_depend>
  1. 打开文件rosed beginner_tutorials CMakeLists.txt,增加依赖,
# Do not just add this line to your CMakeLists.txt, modify the existing line
find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
 message_generation
)
  1. 在CMakeLists.txt文件,增加消息文件,取消#,并修改为
add_message_files(
  FILES
  Num.msg
)
  1. 在CMakeLists.txt文件,增加消息生成包,取消#,并修改为
generate_messages(
  DEPENDENCIES
  std_msgs
)
  1. 在CMakeLists.txt文件,增加消息生成包,取消CATKIN_DEPENDS的#,并修改为
catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES beginner_tutorials
   CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
#  DEPENDS system_lib
)
  1. 编译代码
$ cd ~/catkin_ws
$ catkin_make
  1. 检查服务
  • 命令:
$ rosmsg show beginner_tutorials/Num
  • 效果:
int64 num

编写发布器的步骤

  1. 进入之前建立的包beginner_tutorials
$ roscd beginner_tutorials
  1. 建立Python脚本目录
$ mkdir scripts
$ cd scripts
  1. 访问代码:
https://github.com/ros/ros_tutorials/blob/kinetic-devel/rospy_tutorials/001_talker_listener/talker.py
  1. 新建talker.py文件,设置权限为可执行,并手工输入代码
$ touch talker.py                #生成文件
$ chmod +x talker.py             #设置可执行
$ rosed beginner_tutorials 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解释代码

  • 代码:import rospy

  • 分析:导入rospy包,rospy是ROS的python客户端。参考rospy API接口

  • 代码:from std_msgs.msg import String

  • 分析:

    • 导入python的标准字符处理库
    • String是一个函数,可以另外方式赋值:
msg = String()  
msg.data = str
  • 或者
String(data=str)
  • 参考python的标准函数库

  • 代码:def talker()

  • 分析:定义talker函数,参考如何定义函数

  • 代码:pub = rospy.Publisher('chatter', String, queue_size=10)

  • 分析:定义发布的主题名称chatter, 消息类型String,实质是std_msgs.msg.String, 设置队列条目个数.参考rospy.Publisher API

  • 代码:rospy.init_node('talker', anonymous=True)

  • 分析:

    • 初始化节点,节点名称为talker, 参考rospy.init_node API
    • anonymous=True,要求每个节点都有唯一的名称,避免冲突。这样可以运行多个talker.py
  • 代码:rate = rospy.Rate(10) # 10hz

  • 分析:设置发布的频率,单位是每秒次数,这是每秒10次的频率发布主题,参考rospy.Rate API

  • 代码:rospy.is_shutdown()

  • 分析:用于检测程序是否退出,是否按Ctrl-C 或其他

  • 代码:rospy.loginfo

  • 分析:在屏幕输出日志信息,写入到rosout节点,也可以通过rqt_console来查看。参考rospy.loginfo API

  • 代码:pub.publish(hello_str)

  • 分析:发布信息到主题,参考pub.publish API

  • 代码:rate.sleep()

  • 分析:睡眠一定持续时间,如果参数为负数,睡眠会立即返回。参考 sleep api

  1. 编译代码
$ cd ~/catkin_ws
$ catkin_make
  1. 测试代码
  • 打开新终端,启动roscore
$ roscore 
  • 打开另一个终端,启动talker.py
$rosrun beginner_tutorials talker.py
  • 效果:
aaa@qq.com:~/catkin_ws/src$ rosrun beginner_tutorials talker.py 
[INFO] [WallTime: 1478418967.640556] hello world 1478418967.64
[INFO] [WallTime: 1478418967.741493] hello world 1478418967.74
  1. 查看主题
  • 命令:
$ rostopic echo /chatter
  • 效果:
data: hello world 1478444433.95
---
data: hello world 1478444434.45
---
data: hello world 1478444434.95
---
data: hello world 1478444435.45
---
data: hello world 1478444435.95
---
data: hello world 1478444436.45

编写订阅器的步骤

  1. 访问代码:
https://github.com/ros/ros_tutorials/blob/kinetic-devel/rospy_tutorials/001_talker_listener/listener.py
  1. 进入~/catkin_ws/src/beginner_tutorials/scripts目录,建立listener.py文件
$ roscd beginner_tutorials 
$ cd scripts
$ touch listener.py
$ chmod +x listener.py
$ rosed beginner_tutorials  listener.py
  1. 手工输入如下代码:
#!/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()
  1. 代码分析
  • 代码:rospy.init_node('listener', anonymous=True)

  • 分析:

    • 初始化节点,节点名称为talker, 参考rospy.init_node API
    • anonymous=True,要求每个节点都有唯一的名称,避免冲突。这样可以运行多个listener.py
  • 代码: rospy.Subscriber("chatter", String, callback)

  • 分析:

    • 订阅函数,订阅chatter主题,内容类型是std_msgs.msgs.String。
    • 当有新内容,调用callback函数处理。接受到的主题内容作为参数传递给callback.
  • 代码:rospy.spin()

  • 分析:保持节点运行,直到节点关闭。不像roscpp,rospy.spin不影响订阅的回调函数,因为回调函数有自己的线程。

  1. 编译代码
$ cd ~/catkin_ws
$ catkin_make
  1. 测试代码
  • 打开新终端,启动roscore
$ roscore 
  • 先打开终端运行talker.py, 打开另一个终端,启动listener.py
$rosrun beginner_tutorials listener.py
  • 效果:
aaa@qq.com:~/catkin_ws/src/beginner_tutorials/scripts$ rosrun beginner_tutoals listener.py 
[INFO] [WallTime: 1478442694.947875] /listerner_14737_1478442694294I heard hello world 1478442694.95
[INFO] [WallTime: 1478442695.448907] /listerner_14737_1478442694294I heard hello world 1478442695.45
  1. 也可以使用命令测试listener.py
  • 命令:
$ rostopic pub -r 10 /chatter std_msgs/String "test"
  • 效果:
$ rostopic echo /chatter

data: test
---
data: test
---
data: test
---
data: test
---
data: test
---
data: test
  1. 使用rqt_console命令查看日志输出
  • 命令:
$ rqt_console
  • 效果:
    ROS与Python入门教程-写简单发布器和订阅器(2)
  1. 使用rqt_graph命令查看节点间调用关系
  • 命令:
$ rqt_graph
  • 效果:

ROS与Python入门教程-写简单发布器和订阅器(2)

  1. 运行多个talker.py和listener.py, 查看调用关系
  • 效果:
    ROS与Python入门教程-写简单发布器和订阅器(2)

制作Launch文件

  1. 在beginner_tutorials目录下新建bringup目录
$ roscd beginner_tutorials
$ mkdir -p bringup
  1. 进入bringup, 新建talker-and-listener.launch
$ cd bringup
$ rosed beginner_tutorials talker-and-listener.launch
  1. 手工输入代码:
<launch>
    <node name="talker" pkg="beginner_tutorials" type="talker.py" />
    <node name="listener" pkg="beginner_tutorials" type="listener.py" />
</launch>
  1. 运行launch
  • 命令:
$ roslaunch beginner_tutorials talker-and-listener.launch
  • 效果:

    ROS与Python入门教程-写简单发布器和订阅器(2)