文章目录
0 引言
本文旨在学习用python
语言从零开始创建ROS
基础包,包括如何创建一个发布消息节点,一个接收消息节点,还有如何使用roslaunch
同时启动多个节点,如何编译ROS
工程包等操作。
默认已在Ubuntu
系统中安装ROS
机器人系统,比如Ubuntu18.04-melodic
工程目录tree
# catkin_hw_py/src 目录下
.
├── CMakeLists.txt -> /opt/ros/melodic/share/catkin/cmake/toplevel.cmake
└── helloworld
├── CMakeLists.txt
├── include
├── launch
│ └── talker_listener.launch
├── package.xml
├── scripts
│ ├── listener.py
│ └── talker.py
└── src
👉 本文代码GitHub:https://github.com/MRZHUGH/CSDN/tree/main/ROS/catkin_hw_py/src/helloworld
👉 C++版: https://blog.csdn.net/MRZHUGH/article/details/131454923
1 工作空间创建并初始化
# 新开一个终端
# 创建一个名为catkin_hw_py工作空间,及src子目录
mkdir -p ~/catkin_hw_py/src
# 进入到src文件夹
cd ~/catkin_hw_py/src
# 回到工作空间根目录
cd ..
# 编译工作空间
catkin_make
2 创建ROS程序包
# 切换到src文件夹
cd ~/catkin_hw_py/src
# 创建名为hello_world的ROS程序包,以后创建其他的包也是此方法,只需修改包的名称即可
catkin_create_pkg hello_world roscpp rospy std_msgs
# python脚本一般默认放在src同级的scripts文件夹下
mkdir hello_world/scripts
执行后,src
目录下新建了一个 hello_world
文件夹及子目录和子文件
.
├── CMakeLists.txt -> /opt/ros/melodic/share/catkin/cmake/toplevel.cmake
└── hello_world
├── CMakeLists.txt
├── include
│ └── hello_world
├── package.xml
├── scripts
└── src
3 创建消息节点
3.1 发布消息节点
在 hello_world/scripts
代码资源文件夹下新建发布消息节点的talker.py
文件,详细代码如下:
#! /usr/bin/python
# -*- encoding: utf-8 -*-
import rospy
from std_msgs.msg import String
# talker 函数
def talker():
pub = rospy.Publisher('chatter', String, queue_size=10)
rospy.init_node('talker', anonymous=True) # 初始化节点
rate = rospy.Rate(10) # 发布频率 10 hz
count = 0
while not rospy.is_shutdown():
hello_str = "hello world " + str(count)
rospy.loginfo(hello_str)
pub.publish(hello_str)
count+=1
rate.sleep()
if __name__ == '__main__':
try:
talker()
except rospy.ROSInterruptException:
pass
3.2 接收消息节点
在 hello_world/scripts
代码资源文件夹下新建接收消息节点的listener.py
文件,详细代码如下:
#! /usr/bin/python
# -*- encoding: utf-8 -*-
import rospy
from std_msgs.msg import String
# Subscribe的回调函数
def callback(data):
rospy.loginfo(rospy.get_caller_id() + 'I heard %s', data.data)
def listener():
rospy.init_node('listener', anonymous=True)
rospy.Subscriber('chatter', String, callback)
rospy.spin()
if __name__ == '__main__':
try:
listener()
except rospy.ROSInterruptException:
pass
4 编辑CMakeLists.txt
执行第2
步后,hello_world
文件夹下生成了CMakeLists.txt
,打开编辑:
# 最后添加以下几行
catkin_install_python(PROGRAMS
scripts/talker.py
scripts/listener.py
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
5 编译程序包
# 回到catkin_hw_py工作空间
cd ~/catkin_hw_py/src
# 执行catkin_make编译
catkin_make
6 运行消息节点
# 新开终端
roscore
# 新开终端,运行talker节点
source ~/catkin_hw_py/devel/setup.bash
rosrun hello_world talker
运行后,可以看到已成功创建发布消息的节点,并持续发布消息:
[INFO] [1688701454.731772]: hello world 0
[INFO] [1688701454.831808]: hello world 1
[INFO] [1688701454.931974]: hello world 2
[INFO] [1688701455.032262]: hello world 3
[INFO] [1688701455.132126]: hello world 4
[INFO] [1688701455.231881]: hello world 5
[INFO] [1688701455.332033]: hello world 6
[INFO] [1688701455.431933]: hello world 7
[INFO] [1688701455.532022]: hello world 8
[INFO] [1688701455.632060]: hello world 9
[INFO] [1688701455.732065]: hello world 10
...
# 新开终端,运行listener节点
source ~/catkin_hw_py/devel/setup.bash
rosrun hello_world listener
运行后,可以看到打印已订阅talker发出的消息:
[INFO] [1688701454.736157]: /listener_28433_1688701438477I heard hello world 0
[INFO] [1688701454.833949]: /listener_28433_1688701438477I heard hello world 1
[INFO] [1688701454.936113]: /listener_28433_1688701438477I heard hello world 2
[INFO] [1688701455.036617]: /listener_28433_1688701438477I heard hello world 3
[INFO] [1688701455.136598]: /listener_28433_1688701438477I heard hello world 4
[INFO] [1688701455.235149]: /listener_28433_1688701438477I heard hello world 5
[INFO] [1688701455.336467]: /listener_28433_1688701438477I heard hello world 6
[INFO] [1688701455.434544]: /listener_28433_1688701438477I heard hello world 7
[INFO] [1688701455.536389]: /listener_28433_1688701438477I heard hello world 8
[INFO] [1688701455.636414]: /listener_28433_1688701438477I heard hello world 9
[INFO] [1688701455.736447]: /listener_28433_1688701438477I heard hello world 10
...
7 添加launch启动文件
rosrun
只能启动一个消息节点,可以用ROS
中launch
文件启动多个节点,在hello_world
文件夹中新建launch
文件夹,并在launch
文件夹中新建talker_listener.launch
,打开talker_listener.launch
,添加如下xml
格式的代码:
<launch>
<node name="talker_node" pkg="helloworld" type="talker.py" output="screen"/>
<node name="listener_node" pkg="helloworld" type="listener.py" output="screen"/>
</launch>
node name
: 该节点的名字,相当于代码中ros::init()
中设置的信息,有了它代码中的名称会被覆盖;pkg
: 表示该节点的package
,相当于rosrun
命令后面的第一个参数;type
: 可执行文件的名字,rosrun
命令的第二个参数;是否可以理解为要执行的节点;output=“screen”
: 将标准输出显示在屏幕上而不是记录在日志中
8 重新编译
# 新开终端
# 重新编译前,先给talker_listener.launch可执行权限
sudo chmod +x ~/catkin_hw_py/src/hello_world/launch/talker_listener.launch
# 回到catkin_hw_py工作空间
cd ~/catkin_hw_py
# 重新编译
catkin_make
9 运行launch文件
# 编译后,重新source
source ~/catkin_hw_py/devel/setup.bash
# 运行talker_listener.launch
roslaunch hello_world talker_listener.launch
运行后,自动启动了roscore
, 也启动了talker
和listener
两个消息节点:
SUMMARY
========
PARAMETERS
* /rosdistro: melodic
* /rosversion: 1.14.11
NODES
/
listener_node (helloworld/listener.py)
talker_node (helloworld/talker.py)
ROS_MASTER_URI=http://localhost:11311
process[talker_node-1]: started with pid [28874]
process[listener_node-2]: started with pid [28875]
[INFO] [1688701512.267202]: hello world 0
[INFO] [1688701512.367715]: hello world 1
[INFO] [1688701512.373523]: /listener_nodeI heard hello world 1
[INFO] [1688701512.467861]: hello world 2
[INFO] [1688701512.471853]: /listener_nodeI heard hello world 2
[INFO] [1688701512.567704]: hello world 3
[INFO] [1688701512.571057]: /listener_nodeI heard hello world 3
[INFO] [1688701512.667685]: hello world 4
[INFO] [1688701512.670343]: /listener_nodeI heard hello world 4
[INFO] [1688701512.767794]: hello world 5
[INFO] [1688701512.772516]: /listener_nodeI heard hello world 5
[INFO] [1688701512.867852]: hello world 6
[INFO] [1688701512.872571]: /listener_nodeI heard hello world 6
...
10 查看节点和topic
查看消息node
rosnode list
输出:
/listener_node
/rosout
/talker_node
查看话题topic
rostopic list
输出:
/chatter
/rosout
/rosout_agg
用rqt_graph
查看消息节点node
和话题topic
的关系
至此,成功用python
语言创建一个ROS
基础包,并包含一个发布节点,一个接收节点,一个话题用来传递消息,也学习了基础的ROS
包编译等操作。
⭐️👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍👍🌔