环境说明
ROS版本:ROS Kinetic Kame
Ubuntu版本:Ubuntu 16.04.6 LTS,(
lsb_release -a
)Python版本:Python 2.7.12
CMake 版本:3.5.1
前文已经讲过
以上是这篇文章的基础
以下所有文件都创建在 ws 的工作空间下
topic通讯机制
ROS
中节点间通信,其中一方为消息的发布者,定义为Publisher
,另一方为消息的订阅者,定义为Subscriber
。考虑到消息需要广泛传播,ROS在设计中没有将该中设计为点对点的单一传递,而是有发布者发布数据到Topic
中,想要获得消息的任何一方都可以在
topic
中去获取数据,类似于udp的广播机制,大致的通讯原理如下图:
使用命令
catkin_create_pkg demo_topic roscpp rospy rosmsg
创建一个名为demo_topic
的包
创建只发布std消息的节点
c++版本
- 在
src
目录下创建一个publisher.cc
文件,将以下代码添加到该文件中
1 |
// 导入 ros 头文件 |
- 在
CMakeLists.txt
中添加add_executable
和target_link_libraries
1 |
# 添加一个可执行程序 |
-
创建
Publisher
对象- 导入要发送的消息的头文件
1
2// 先使用 std 库中的简易消息
- 创建对象,并发送消息
1
2
3
4
5
6
7
8
9
10
11
12
13// 创建一个 topic 的名称
char topic_name[] = "demo_topic";
// 获取一个 publisher 的对象
const ros::Publisher &pub =
node.advertise<std_msgs::String>(topic_name, 1000);
// 创建一个要发送的消息对象
std_msgs::String str;
// 填充要发送的数据
str.data = "I send a message";
// 使用 publisher 发送该消息
while (ros::ok()) {
pub.publish(str);
} -
编译该节点,在工作空间目录下
1 |
catkin_make |
Python版本
- 在
package
目录下创建一个名为scripts
的文件夹 - 创建一个名为
publisher.py
的文件,将以下代码添加到该文件中
1 |
#!/usr/bin/env python |
-
创建
Publisher
对象- 导入要发送的消息的头文件
1
2# 先使用 std 库中的简易消息
from std_msgs.msg import String- 创建对象,并发送消息
1
2
3
4
5
6
7
8
9
10
11# 创建一个 topic 名称
topic_name = "demo_topic"
# 创建一个发布者
pub = rospy.Publisher(topic_name, String, queue_size=1000)
# 创建一个要发布的消息
string = String()
# 填充要发布的消息
string.data = "I send a message"
# 使用 publisher 发送该消息
while not rospy.is_shutdown():
pub.publish(string) -
给 publisher.py 赋予可执行权限
1 |
chmod a+x src/demo_topic/scripts/publisher.py |
使用 rqt_topic 工具调试
- 将当前工作空间的环境变量添加到
bash
或zsh
中
1 |
# 根据使用不同的 shell 使用不同的环境变量,两者选其一 |
-
运行 demo_publisher
- c++ 程序
1
rosrun demo_topic demo_publisher
- python 程序
1
rosrun demo_topic publisher.py
-
打开 rqt_topic 工具
1 |
rosrun rqt_topic rqt_topic |
- 勾选 demo_topic,结果如下
创建发布自定义消息的节点
我们使用在ros消息讲过的demo_msgs
包中的Team.msg
来传输数据
c++版本
- 在
src
目录下创建一个publisher1.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
5
6
7
8
9
10
11
12
13
14
15
16
17// 创建一个 topic 的名称
char topic_name[] = "demo_topic";
// 获取一个 publisher 的对象
const ros::Publisher &pub =
node.advertise<demo_msgs::Team>(topic_name, 1000);
// 创建一个要发送的消息对象
demo_msgs::Team team;
// 填充要发送的数据
team.name = "I'm a team";
team.leader.name = "AskeyNil";
team.leader.age = 18;
team.location.angular.x = 1;
team.location.linear.z = 2;
// 使用 publisher 发送该消息
while (ros::ok()) {
pub.publish(team);
} -
-
编译该节点,在工作空间目录下
1 |
catkin_make |
python版本
- 在
package
目录下创建一个名为scripts
的文件夹 - 创建一个名为
publisher1.py
的文件,将以下代码添加到该文件中
1 |
#!/usr/bin/env python |
-
创建
Publisher
对象- 导入要发送的消息的头文件
1
from demo_msgs.msg import Team
- 创建对象,并发送消息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# 创建一个 topic 名称
topic_name = "demo_topic"
# 创建一个发布者
pub = rospy.Publisher(topic_name, Team, queue_size=1000)
# 创建一个要发布的消息
team = Team()
# 填充要发布的消息
team.name = "I'm a team"
team.leader.name = "AskeyNil"
team.leader.age = 18
team.location.angular.x = 1
team.location.linear.z = 2
# 使用 publisher 发送该消息
while not rospy.is_shutdown():
pub.publish(team) -
给 publisher.py 赋予可执行权限
1 |
chmod a+x src/demo_topic/scripts/publisher.py |
使用 rqt_topic 工具调试
- 将当前工作空间的环境变量添加到
bash
或zsh
中
1 |
# 根据使用不同的 shell 使用不同的环境变量,两者选其一 |
-
运行 demo_publisher
- c++ 程序
1
rosrun demo_topic demo_publisher1
- python 程序
1
rosrun demo_topic publisher1.py
-
打开 rqt_topic 工具
1 |
rosrun rqt_topic rqt_topic |
- 勾选 demo_topic,结果如下
总结
- 如果调用别的
package
中的消息,需要将对应package
添加到CMakeLists.txt
中即可使用 - Python 文件在调用之前一定要给对应的程序可执行的权限
- 创建简单ros程序的时候有大致的固定格式,可以使用代码块将其包装起来,下文记录我在
vscode
中记录的代码块 - 注意:
node_name
是一个base name,其中不能包含/
。 - 注意:如果发送频率太高,缓冲区中的消息大于我们设定的值,本文设置的是1000,则会默认丢弃掉最先发布的消息。
代码块
C++
ros_main
1 |
"ros_main": { |
ros_create_publisher
1 |
"ros_create_publisher": { |
Python
ros_main
1 |
"ros_main": { |
ros_create_publisher
1 |
"ros_create_publisher": { |
附录
创建只发布std消息的节点的完整代码
C++
1 |
|
Python
1 |
#!/usr/bin/env python |
创建发布自定义消息的节点
C++
1 |
|
Python
1 |
#!/usr/bin/env python |