引言
机器人操作系统(Robot Operating System, ROS)是一个开源的元操作系统,用于开发机器人的软件。它并不是一个真正的操作系统,而是一套软件框架和服务,设计用来帮助开发者构建复杂的机器人系统。ROS提供了硬件抽象、设备驱动、库、消息传递和工具包等,使得机器人软件的开发变得更为简单。
本教程将指导你如何在ROS1环境中编写一个简单的自定义节点。我们将从新建工作空间开始,逐步介绍如何创建一个新的ROS包,并在此基础上实现一个基本的节点,该节点能够实现发布和订阅信息的功能。
创建新的ROS工作空间
创建工作空间目录src
我们要在文件系统中创建一个新的目录来作为我们的工作空间。工作空间通常包含三个子目录:src用于存放源代码,build用于存放编译过程中生成的中间文件,devel用于存放编译后的可执行文件和其他产品,build目录和devel目录是在工作空间编译之后自动生成的。下面先新建终端,并创建一个新的工作空间目录:
mkdir -p ~/catkin_ws/src
cd ~/catkin_ws/src
然后初始化新的catkin工作空间。这可以通过运行catkin_init_workspace命令完成,在终端输入:
catkin_init_workspace
之后我们可以新建一个ROS功能包,在终端输入以下指令:
catkin_create_pkg beginner_tutorials rospy roscpp std_msgs
beginner_tutorials 是功能包的名称,rospy roscpp std_msgs则是这个功能包的基础依赖。至此我们的工作空间就创建完成了,后面我们可以编写具体节点实现指定功能。
编写自定义节点
- 创建发布者节点:在beginner_tutorials包目录下创建一个名为scripts的文件夹,再在该目录下创建一个名为talker.py的Python脚本,在终端输入:
cd ~/catkin_ws/scripts
gedit talker.py
- 在打开的文本编辑器里面,输入以下代码:
#!/usr/bin/env python
#encoding=utf-8
import rospy
from std_msgs.msg import String
def talker():
pub = rospy.Publisher('chatter', String, queue_size=10)
rospy.init_node('talker', anonymous=True)
rate = rospy.Rate(1) # 1 Hz
count = 0
while not rospy.is_shutdown():
hello_str = "hello world %d" % count
rospy.loginfo(hello_str)
pub.publish(hello_str)
rate.sleep()
count += 1
if __name__ == '__main__':
try:
talker()
except rospy.ROSInterruptException:
pass
- 为了使这个脚本能够直接运行,我们可以给它添加执行权限,在终端输入以下指令:
chmod +x scripts/talker.py
- 对于订阅者节点,我们也是同样的操作。在scripts文件目录下创建一个名为listener.py的Python脚本,在终端输入:
gedit listener.py
- 然后在打开的文本编辑器里面添加以下代码:
#!/usr/bin/env python
#encoding=utf-8
import rospy
from std_msgs.msg import String
def callback(data):
rospy.loginfo("I heard %s", data.data)
def listener():
rospy.init_node('listener', anonymous=True)
rospy.Subscriber("chatter", String, callback)
rospy.spin()
if __name__ == '__main__':
listener()
- 同样的,我们给这个python脚本赋权,在终端输入:
chmod +x scripts/listener.py
- 这里提一下,python脚本也可以放在src文件目录下,这个没有固定规定,只是说按照大多数人的习惯,我们将脚本放置在了scripts文件目录下。
编译工作空间并测试
- 编译工作空间,在终端输入:
cd ~/catkin_ws
catkin_make
- 设置环境变量,在终端输入:
source devel/setup.bash
如果我们想要更加方便的话,可以在主目录下的.bashrc文件里面最后一行添加并保存,这样我们每次想要执行相应的功能文件就不需要先输入上面这行指令了:
source your_devel_setup.bash_path/setup.bash
- 运行节点测试,启动发布者终端,在终端输入:
rosrun beginner_tutorials talker.py
新建终端,依次输入,这里注意文件目录需要和第一个终端保持一致,启动订阅者节点:
source devel/setup.bash
rosrun beginner_tutorials listener.py
最后我们在终端可以看到:
I heard hello world X #其中X是从0开始递增的数字
补充:包管理与配置文件
此外,我们可以看看如何更好地管理ROS包中的文件。在ROS包中,有两个重要的配置文件:package.xml和CMakeLists.txt。这两个文件分别负责描述包的元数据和构建指令。在对原文件做出修改之后,我们需要关注以下这两个文件,当然对于python脚本,保存即生效,只做小的改动,大多时候不需要关注这两个文件,对于用c++编写的功能文件,则需要对这两个文件有更高的关注度。
更新package.xml
package.xml文件用来描述ROS包的基本信息和依赖关系。确保你的package.xml文件包含正确的依赖项:
<?xml version="1.0"?>
<package>
<name>beginner_tutorials</name>
<version>0.0.0</version>
<description>The beginner tutorials package</description>
<maintainer email="your.email@example.com">Your Name</maintainer>
<license>BSD</license>
<buildtool_depend>catkin</buildtool_depend>
<depend>rospy</depend>
<depend>std_msgs</depend>
<export>
<build_type>catkin</build_type>
</export>
</package>
更新CMakeLists.txt
CMakeLists.txt文件用来定义构建过程。确保你的CMakeLists.txt文件正确设置了包的依赖关系,并且指定了要构建的可执行文件:
cmake_minimum_required(VERSION 2.8.3)
project(beginner_tutorials)
# Find catkin macros and libraries
find_package(catkin REQUIRED COMPONENTS
rospy
std_msgs
)
catkin_package(
CATKIN_DEPENDS
rospy
std_msgs
)
# Specify additional locations of header files
include_directories(
${catkin_INCLUDE_DIRS}
)
# Declare a ROS node executable
add_executable(talker src/talker.py)
add_executable(listener src/listener.py)
重新构建并测试
最后,回到工作空间的根目录,重新构建工作空间,然后再次运行发布者和订阅者节点:
cd ~/catkin_ws
catkin_make
source devel/setup.bash
rosrun beginner_tutorials talker.py & rosrun beginner_tutorials listener.py
小结
在本次ROS1(Robot Operating System 1)入门教程中,我们详细介绍了如何创建一个基本的自定义节点(Node),这对于初学者来说是一个重要的起步阶段。大家对创建和运行简单ROS节点有了基本的了解,在后续的学习过程中,大家可以学着逐步扩展其功能,探索更高级的主题,如服务调用、动作(Action)客户端和服务端的实现等,我也会持续跟进。