栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

ROS 笔记(05)— 发布者 Publisher 和订阅者subscriber 的 Python 实现

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

ROS 笔记(05)— 发布者 Publisher 和订阅者subscriber 的 Python 实现

机器人是一种高度复杂的系统性实现,在机器人上可能集成各种传感器(雷达、摄像头、GPS…)以及运动控制实现,为了解耦合,在 ROS 中每一个功能点都是一个单独的进程,每一个进程都是独立运行的。

更确切的讲,ROS 是进程(也称为Nodes)的分布式框架。 因为这些进程甚至还可分布于不同主机,不同主机协同工作,从而分散计算压力。不过随之也有一个问题: 不同的进程是如何通信的?也即不同进程间如何实现数据交换的?在此我们就需要介绍一下 ROS 中的通信机制了。

ROS 中的基本通信机制主要有如下三种实现策略:

  • 话题通信(发布订阅模式)
  • 服务通信(请求响应模式)
  • 参数服务器(参数共享模式)

话题通信是 ROS 中使用频率最高的一种通信模式,话题通信是基于发布订阅模式的,也即:一个节点发布消息,另一个节点订阅该消息。话题通信的应用场景也极其广泛,比如下面一个常见场景:

机器人在执行导航功能,使用的传感器是激光雷达,机器人会采集激光雷达感知到的信息并计算,然后生成运动控制信息驱动机器人底盘运动。

在上述场景中,就不止一次使用到了话题通信。

  • 以激光雷达信息的采集处理为例,在 ROS 中有一个节点需要时时的发布当前雷达采集到的数据,导航模块中也有节点会订阅并解析雷达数据。
  • 再以运动消息的发布为例,导航模块会根据传感器采集的数据时时的计算出运动控制信息并发布给底盘,底盘也可以有一个节点订阅运动信息并最终转换成控制电机的脉冲信号。

以此类推,像雷达、摄像头、GPS… 等等一些传感器数据的采集,也都是使用了话题通信,换言之,话题通信适用于不断更新的数据传输相关的应用场景。

1. 发布者 Publisher 1.1 话题模型

首先我们要实现下图所示的话题模型,该模型如下图所示,该模型中涉及到三个角色:

  • ROS Master (管理者)
  • Talker (发布者)
  • Listener (订阅者)

ROS Master 负责保管 Talker 和 Listener 注册的信息,并匹配话题相同的 Talker 与 Listener,帮助 Talker 与 Listener 建立连接,连接建立后,Talker 可以发布消息,且发布的消息会被 Listener 订阅。

其中,主题名称节点为 /turtle1/cmd_vel ,发布者和订阅者的消息类型为 geometry_msgs::Twist 。

1.2 创建功能包

在 src 目录下创建功能包,包名为 topic_demo,依赖分别为 rospy 、 std_msgs 、 geometry_msgs。

wohu@wohu-pc:~/project/ros/ros_demo/src$ catkin_create_pkg  topic_demo rospy std_msgs geometry_msgs 

输出如下:

turtlesim Created file topic_demo/package.xml
Created file topic_demo/CMakeLists.txt
Created folder topic_demo/src
Successfully created files in /home/wohu/project/ros/ros_demo/src/topic_demo. Please adjust the values in package.xml.
1.3 创建发布者代码

在功能包下面建立一个 scripts 文件夹,在 scripts 文件里面建立一个 .py 文件。


publisher.py 代码内容:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# 该例程将发布turtle1/cmd_vel话题,消息类型geometry_msgs::Twist

import rospy
from geometry_msgs.msg import Twist

def velocity_publisher():
	# ROS节点初始化
    rospy.init_node('velocity_publisher', anonymous=True)

	# 创建一个Publisher,发布名为/turtle1/cmd_vel的topic,消息类型为geometry_msgs::Twist,队列长度10
    turtle_vel_pub = rospy.Publisher('/turtle1/cmd_vel', Twist, queue_size=10)

	#设置循环的频率
    rate = rospy.Rate(10) 

    while not rospy.is_shutdown():
		# 初始化geometry_msgs::Twist类型的消息
        vel_msg = Twist()
        vel_msg.linear.x = 0.5
        vel_msg.angular.z = 0.2

		# 发布消息
        turtle_vel_pub.publish(vel_msg)
    	rospy.loginfo("Publsh turtle velocity command[%0.2f m/s, %0.2f rad/s]", 
				vel_msg.linear.x, vel_msg.angular.z)

		# 按照循环频率延时
        rate.sleep()

if __name__ == '__main__':
    try:
        velocity_publisher()
    except rospy.ROSInterruptException:
        pass
1.4 修改 Python 代码可执行权限
$ chmod +x publisher.py 
1.5 运行发布者代码
  • 执行 roscore 启动 ROS 服务
$ roscore
  • 启动小海龟仿真器
    我们再打开一个终端,执行如下命令
$ rosrun turtlesim turtlesim_node 
  • 运行发布者代码
$ rosrun topic_demo publisher.py

rosrun 后面跟着创建的包名 topic_demo 和发布者的文件 publisher.py

演示结果如下:

如果运行后报错:

$ rosrun topic_demo publisher.py 
[rosrun] Couldn't find executable named publisher.py below /home/wohu/project/ros/ros_demo/src/topic_demo
[rosrun] Found the following, but they're either not files,
[rosrun] or not executable:
[rosrun]   /home/wohu/project/ros/ros_demo/src/topic_demo/scripts/publisher.py
wohu@wohu-pc:~/project/ros/ros_demo/src$

说明 publisher.py 文件权限没有修改。

2. 订阅者subscriber

和前面一样,在功能包 topic_demo 目录的 src 目录下存放订阅者文件


订阅者代码实现

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# 该例程将订阅/turtle1/pose话题,消息类型turtlesim::Pose

import rospy
from turtlesim.msg import Pose

def poseCallback(msg):
    rospy.loginfo("Turtle pose: x:%0.6f, y:%0.6f", msg.x, msg.y)

def pose_subscriber():
	# ROS节点初始化
    rospy.init_node('pose_subscriber', anonymous=True)

	# 创建一个Subscriber,订阅名为/turtle1/pose的topic,注册回调函数poseCallback
    rospy.Subscriber("/turtle1/pose", Pose, poseCallback)

	# 循环等待回调函数
    rospy.spin()

if __name__ == '__main__':
    pose_subscriber()

依次分别打开 3 个终端执行下面命令:

$ roscore 
$ rosrun turtlesim turtlesim_node 
$ rosrun turtlesim turtle_teleop_key

通过下面命令启动订阅者

$ rosrun topic_demo pose_subscriber.py

通过上、下、左、右 控制海龟移动,然后就可以看到 pose_subscriber.py 脚本输出海龟的位置信息了。

3. 其它

经过测试验证,publisher.py 代码也可以放在 src 目录下


更改脚本名称后运行下面命令,也是可以运行起来的。

$ rosrun topic_demo publisher_demo.py
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/982471.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号