环境说明
ROS版本:ROS Kinetic Kame
Ubuntu版本:Ubuntu 16.04.6 LTS,(
lsb_release -a
)Python版本:Python 2.7.12
CMake 版本:3.5.1
前文已经讲过
以上是这篇文章的基础
以下所有文件都创建在 ws 的工作空间下
创建只订阅std消息的节点
c++版本
- 在
src
目录下创建一个subscriber.cc
文件,将以下代码添加到该文件中
1 |
// 导入 ros 头文件 |
- 在
CMakeLists.txt
中添加add_executable
和target_link_libraries
1 |
# 添加一个可执行程序 |
-
创建
Subscriber
对象- 导入要订阅的消息的头文件
1
2// 先使用 std 库中的简易消息
- 创建对象,并订阅消息
1
2
3
4// 创建一个 topic 的名称
char topic_name[] = "demo_topic";
// 创建一个 Subscriber 对象
const ros::Subscriber &sub = node.subscribe(topic_name, 1000, subCallback);- 创建回调函数
1
2
3
4void subCallback(const std_msgs::String::ConstPtr &msg) {
// 一般写业务逻辑,此处打印接收到的数据
ROS_INFO_STREAM(msg->data);
} -
编译该节点,在工作空间目录下
1 |
catkin_make |
python版本
- 在
package
目录下创建一个名为scripts
的文件夹 - 创建一个名为
subscriber.py
的文件,将以下代码添加到该文件中
1 |
#!/usr/bin/env python |
-
创建
Subscriber
对象- 导入要订阅的消息的头文件
1
2# 先使用 std 库中的简易消息
from std_msgs.msg import String- 创建对象,并订阅消息
1
2
3
4# 创建一个 topic 名称
topic_name = "demo_topic"
# 创建一个 Subscriber 对象
sub = rospy.Subscriber(topic_name, String, subCallback)- 创建回调函数
1
2
3
4# 注意这个赋默认值是为了使后面有代码提示,实际过程中,msg 被传入的,所以不影响结果
def subCallback(msg=String()):
# 一般写业务逻辑,此处打印接收到的数据
print (msg.data)
- 给 subscriber.py 赋予可执行权限
1 |
chmod a+x src/demo_topic/scripts/subscriber.py |
使用 rqt_publisher 工具调试
- 将当前工作空间的环境变量添加到
bash
或zsh
中
1 |
# 根据使用不同的 shell 使用不同的环境变量,两者选其一 |
-
运行 demo_publisher
- c++ 程序
1
rosrun demo_topic demo_subscriber
- python 程序
1
rosrun demo_topic subscriber.py
-
打开 rqt_publisher 工具
1 |
rosrun rqt_publisher rqt_publisher |
- 选择我们对应的
Topic
:demo_topic
,Type
选择std_msgs/String
- 勾选就会一直发送数据,或者右键点击
Publisher Selected Once
可以发送一次数据
创建订阅自定义消息的节点
我们使用在ros消息讲过的demo_msgs
包中的Team.msg
来传输数据
c++版本
- 在
src
目录下创建一个subscriber1.cc
文件,将以下代码添加到该文件中
1 |
// 导入 ros 头文件 |
- 在
CMakeLists.txt
中添加add_executable
和target_link_libraries
1 |
# 添加一个可执行程序 |
- 在
CMakeLists.txt
文件的find_package
中添加demo_msgs
的依赖
1 |
find_package(catkin REQUIRED COMPONENTS |
-
创建
Publisher
对象-
导入要发送的消息的头文件
1
-
创建对象,并发送消息
1
2
3
4// 创建一个 topic 的名称
char topic_name[] = "demo_topic";
// 创建一个 Subscriber 对象
const ros::Subscriber &sub = node.subscribe(topic_name, 1000, subCallback);- 创建回调函数
1
2
3
4void subCallback(const demo_msgs::Team::ConstPtr &msg) {
// 一般写业务逻辑,此处打印接收到的数据
ROS_INFO_STREAM(msg->name);
} -
-
编译该节点,在工作空间目录下
1 |
catkin_make |
python版本
- 在
package
目录下创建一个名为scripts
的文件夹 - 创建一个名为
subscriber1.py
的文件,将以下代码添加到该文件中
1 |
#!/usr/bin/env python |
-
创建
Subscriber
对象- 导入要订阅的消息的头文件
1
from demo_msgs.msg import Team
- 创建对象,并订阅消息
1
2
3
4# 创建一个 topic 名称
topic_name = "demo_topic"
# 创建一个 Subscriber 对象
sub = rospy.Subscriber(topic_name, Team, subCallback)- 创建回调函数
1
2
3
4# 注意这个赋默认值是为了使后面有代码提示,实际过程中,msg 被传入的,所以不影响结果
def subCallback(msg=Team()):
# 一般写业务逻辑,此处打印接收到的数据
print (msg.name)
- 给 subscriber.py 赋予可执行权限
1 |
chmod a+x src/demo_topic/scripts/subscriber1.py |
使用 rqt_publisher 工具调试
- 将当前工作空间的环境变量添加到
bash
或zsh
中
1 |
# 根据使用不同的 shell 使用不同的环境变量,两者选其一 |
-
运行 demo_publisher
- c++ 程序
1
rosrun demo_topic demo_subscriber
- python 程序
1
rosrun demo_topic subscriber.py
-
打开 rqt_publisher 工具
1 |
rosrun rqt_publisher rqt_publisher |
- 选择我们对应的
Topic
:demo_topic
,Type
选择demo_msgs/Team
- 勾选就会一直发送数据,或者右键点击
Publisher Selected Once
可以发送一次数据
总结
- 两种订阅消息几乎是一样的,因为在我们创建包的时候已经将
std_msgs
的依赖导入了,所以导致我们就不需要添加依赖。 - 使用对应消息的时候要添加对应消息的依赖。
- 回调函数默认在主线程中进行,即
ros::spin()
或rospy.spin()
会卡死主线程,进入ros的运行时 - 如果有别的运行时,如 qt(以后会详细介绍qt中的用法),则需要使用异步接收ros的运行时消息,或者在 qt 中使用
spinOnce()
(仅在c++中需要)
代码块
C++
ros_create_subscriber
1 |
"ros_create_subscriber": { |
Python
ros_create_subscriber
1 |
"ros_create_subscriber": { |
附录
创建只发布std消息的节点的完整代码
C++
1 |
|
Python
1 |
#!/usr/bin/env python |
创建发布自定义消息的节点
C++
1 |
|
Python
1 |
#!/usr/bin/env python |