ROS 系列学习教程(总目录)
ROS2 系列学习教程(总目录)
一、创建工作空间目录
前面已经创建了 ros2_learning
,如果没有创建,使用过如下指令创建:
# 递归创建工作空间目录
mkdir -p ros2_learning/src
二、创建功能包
注意编译系统选择 ament_python
cd ros2_learning/src
ros2 pkg create --build-type ament_python hello_world_py
其中,
使用 --build-type
指定编译系统为 ament_python
hello_world_py:自定义功能包名称
结果如下图:
其中,有 [WARNING]: Unknown license 'TODO: License declaration'.
ROS2建议创建一个 License 文件以说明该功能包的发布许可。可以使用 --license LICENSE
参数指定。
ros2 pkg create --build-type ament_python --license Apache-2.0 hello_world_py
生成的目录结构如下:
hello_world_py
├── hello_world_py
│ └── __init__.py
├── LICENSE
├── package.xml
├── resource
│ └── hello_world_py
├── setup.cfg
├── setup.py
└── test
├── test_copyright.py
├── test_flake8.py
└── test_pep257.py
三、编辑源文件
在 hello_world_py/hello_world_py
目录下新增 publisher.py
文件,文件内容如下:
import rclpy
from rclpy.node import Node
from std_msgs.msg import String
class HelloWorldPublisher(Node):
def __init__(self):
super().__init__('publisher')
self.count_ = 0
self.publisher_ = self.create_publisher(String, '/hello_world', 10)
timer_period = 1.0 # seconds
self.timer_ = self.create_timer(timer_period, self.timer_callback)
def timer_callback(self):
msg = String()
msg.data = f"Hello, world! {
self.count_}"
self.get_logger().info(f"Publishing: '{
msg.data}'")
self.publisher_.publish(msg)
self.count_ += 1
def main(args=None):
rclpy.init(args=args)
hello_world_publisher_node = HelloWorldPublisher()
rclpy.spin(hello_world_publisher_node) # 启动节点的事件循环
hello_world_publisher_node.destroy_node() # 清理并关闭节点
rclpy.shutdown() # 关闭ROS2
if __name__ == '__main__':
main()
四、编辑编译配置文件setup.py
找到ros2_learning/src/hello_world_py/setup.py
,修改如下:
setup.py
文件说明如下:
# setuptools 用于简化包的构建、分发和安装过程
from setuptools import find_packages, setup
# 包名称
package_name = 'hello_world_py'
# 调用setup配置包信息
setup(
name=package_name, # 包名称
version='0.0.0', # 版本号,主版本号.次版本号.修订号
# 自动发现项目中的包。exclude=['test']参数告诉find_packages忽略名为test的目录
packages=find_packages(exclude=['test']),
# 指定与包一起安装的数据文件
# 元组第一项:目标安装路径
# 元组第二项:要安装到目标路径的文件路径列表。这些路径是相对于setup.py文件所在目录的。
data_files=[
('share/ament_index/resource_index/packages',
['resource/' + package_name]),
('share/' + package_name, ['package.xml']),
],
install_requires=['setuptools'], # 包安装时所需的依赖项
zip_safe=True, # 指定包是否可以作为zip文件安全地安装和运行
maintainer='vistar', # 指定包的维护者姓名
maintainer_email='[email protected]', # 指定维护者的电子邮件地址
description='TODO: Package description', # 包的简短描述
license='Apache-2.0', # 包的许可证类型
tests_require=['pytest'], # 指定运行测试所需的依赖项
# 定义入口点,即将包内的函数或类暴露为命令行工具
entry_points={
'console_scripts': [
# 定义一个名为talker的命令行工具,映射到hello_world_py.publisher模块中的main函数
"talker = " + package_name + ".publisher:main",
],
},
)
五、编译工程
进入到工作空间 ros2_learning 目录,执行如下指令编译该工程:
colcon build
编译成功后,会在ros2_learning目录下生成 build
、install
和 log
目录。
- build: 存放编译过程中产生的中间文件,包括临时文件、对象文件、依赖关系等。用户通常不需要直接访问这个目录,因为构建工具会自动管理其中的内容。然而,在调试构建问题时,有时可能需要查看这个目录中的文件以获取更多信息。
- install: 存放最终编译生成的可执行文件、库文件、配置文件、环境设置文件等资源。这些资源是构建完成后准备发布的独立包,可以被其他项目或用户直接使用。通常包含多个子目录,如bin(可执行文件)、lib(库文件)、share(配置文件、资源文件等)等。用户可以在 install 目录中查找可执行文件或库文件来运行或链接ROS2节点或服务。此外,ROS2环境设置文件(如setup.bash)也存放在该目录,用于将ROS2包添加到用户的 PATH 和其他环境变量中。
- log: 存放编译和运行过程中产生的各种日志信息。这些日志信息包括警告、错误、信息等,对于调试和监控 ROS2 系统的运行状态非常有用。这些日志文件可以是文本文件,也可以是其他格式的文件,具体取决于 ROS2 日志系统的配置。用户可以通过查看log目录中的日志文件来了解 ROS2 系统在编译或运行过程中的行为。此外,ROS2 还提供了日志查看工具(如rqt_console),这些工具可以方便地查看和分析日志文件中的内容。
六、运行节点
生成的节点在 install/hello_world_py/lib/hello_world_py
中,我们可以直接执行:
不过这样需要知道节点的具体路径,实际中操作较麻烦。
ROS2 提供了 run
命令,可以根据包名和节点名,在任何目录执行。
但需要先设置环境变量,即让系统可以找到节点,进入到工作空间目录,执行如下指令:
source install/setup.bash
但单次执行 source install/setup.bash
只对当前终端有效,新打开终端仍需再执行该命令,为了避免每次执行,可以把该命令加到当前用户的 .bashrc
文件中,该文件在用户的 home
目录下。
方法一:直接打开 ~/.bashrc
文件,在末尾添加 source 你的工作空间目录/install/setup.bash
,保存。
方法二:使用命令 echo "source 你的工作空间目录/install/setup.bash" >> ~/.bashrc
最后,使用命令 source ~/.bashrc
使修改生效。
运行 talker 节点后,还可以通过 topic 指令订阅 talker 发布的信息,如下: