ROS中用python实现topic通信
一、创建ROS工作空间
- 在/home/USENAME/目录下创建一个ros文件夹,以后所有的ros工作空间都放在该文件夹下。
mkdir ros && cd ros
- 创建工作空间文件夹,这里相当于Java或者C++的工程根目录。
mkdir -p my_ws/src && cd my_ws/src
- 初始化工作空间
catkin_init_workspace
,src目录下会出现一个cmake文件。
- 编译工作空间
cd .. && catkin_make
,编译成功之后有三个文件夹:
- build:存放在工作空间编译过程中产生的文件。
- devel:存放编译生成的库和脚本。
- src:存放功能包。
- 刷新当前环境变量
source devel/setup.bash
,在当前终端下运行rosrun命令就可以直接找到==在/my_ws/src/目录==下的功能包。如果不想每次打开终端都要source一下,可以把上面的source命令写到/.bashrc文件的最后一行。
sudo gedit ~/.bashrc
二、创建功能包
- 用
catkin_create_pkg
命令在/my_ws/src/目录下创建一个名为my_pkg的功能包。这个功能包依赖功能包有roscpp:c++ rospy:python std_msgs:ros的标准消息格式
catkin_create_pkg my_pkg roscpp rospy std_msgs
- 创建成功之后,功能包目录下有上述四个文件。
- include:一般用来存放h/hpp头文件。
- src:一般用来存放C++代码。
- CMakeList.txt:该功能包的cmake文件。
- package.xml:和名字一样,存该功能包依赖的包的信息、当前功能包功能 的描述、版本等。
- 重新编译当前工作空间
cd ../../ && catkin_make
,编译信息会提示当前工作空间多了一个功能包。
三、实现topic发布
- 进入刚刚创建的工作空间下,创建scripts文件夹来存放python脚本。
mkdir scripts
- 在Ubuntu下,可以直接从vscode官网下载vscode来写python代码。下面的代码全部参考自B站【古月居】。https://www.bilibili.com/video/BV1zt411G7Vn?from=search&seid=16218413685944115930
- 我们创建一个名字为my_publisher.py的python脚本来发布ros标准消息库里的std_msgs/String类型的消息。
from std_msgs.msg import String
导入String类型消息格式。rospy.init_node('my_publisher', anonymous=True)
初始化发布者节点。my_topic = rospy.Publisher('/my_topic', String, queue_size=10)
创建一个topic话题,缓冲队列的长度是10个msg。rate = rospy.Rate(1)
表示发送msg的频率,单位是hz。- 查看String的消息格式是:
-my_topic.publish(string_msg)
向topic中发布msg。
#!/usr/bin/python2.7
#-*- coding:UTF-8 -*-
# 导入ros的python依赖
import rospy
from std_msgs.msg import String
def my_publisher():
# Ros 节点初始化
rospy.init_node('my_publisher', anonymous=True)
# 创建一个Publisher,发布名为/my_topic,消息类型为std_msgs/String,队列长度 10
my_topic = rospy.Publisher('/my_topic', String, queue_size=10)
# 设置循环的频率
rate = rospy.Rate(1)
while not rospy.is_shutdown():
# 初始化 std_msgs/String 类型的 msg 对象
string_msg = String()
string_msg.data = 'This is my_publisher.'
# 发消息
my_topic.publish(string_msg)
rospy.loginfo("Publish String message %s", string_msg)
# 按照循环频率延时
rate.sleep()
if __name__ == '__main__':
try:
my_publisher()
except rospy.ROSInterruptException:
pass
- 把上面的python脚本的权限调整为可执行文件。
然后运行脚本rosrun my_pkg my_publisher.py
四、实现topic的接收
步骤在代码中有注释。
- ros中接收节点是要通过回调函数来接收从topic传来的msg并处理的。
- 把python脚本的权限改为可执行。
#!/usr/bin/python2.7
#-*- coding:UTF-8 -*-
import rospy
from std_msgs.msg import String
def MyInfoCallback(msg):
rospy.loginfo("Received String message %s", msg)
def my_subcriber():
# ROS节点初始化
rospy.init_node('my_subcriber', anonymous=True)
# 创建一个Subcriber,订阅名为 /my_topic 的topic,注册回调函数 MyInfoCallback()
rospy.Subscriber("/my_topic", String, MyInfoCallback)
# 循环等待回调函数
rospy.spin()
if __name__ == '__main__':
my_subcriber()